[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
gEDA-cvs: geda_manager.git: branch: master updated (0c9751236b273a4f68cd0d786ebbbc41be99f5ab)
The branch, master has been updated
via 0c9751236b273a4f68cd0d786ebbbc41be99f5ab (commit)
from 986e3d5ef078297f21398afe3d3c92beb49db37f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
gedamanager.py | 38 +
images/bitmaps/cog.png | Bin 0 -> 512 bytes
images/bitmaps/page_white_acrobat.png | Bin 0 -> 591 bytes
images/bitmaps/page_white_error.png | Bin 623 -> 0 bytes
images/bitmaps/page_white_text.png | Bin 0 -> 342 bytes
src/gedamanager.py | 1466 --------------
src/{gsch2pcb.py => gui/Gsch2pcb.py} | 48 +-
src/{gsch2pcb.py => gui/Gsch2pcb.py.~1~} | 8 +-
src/gui/MainWindow.py | 380 ++++
src/gui/MainWindow.py.~1~ | 642 +++++++
src/gui/MainWindow.py.~2~ | 2013 ++++++++++++++++++++
src/{newproject.py => gui/NewProject.py} | 28 +-
src/{newproject.py => gui/NewProject.py.~1~} | 4 +-
src/gui/Preferences.py | 109 ++
src/gui/Preferences.py.~1~ | 112 ++
ChangeLog => src/gui/__init__.py | 0
src/gui/new.py.~1~ | 2 +
src/gui/new.py.~2~ | 2007 +++++++++++++++++++
src/gui/temp.py.~1~ | 1 +
src/{ => gui/xml}/file_popup.xml | 0
src/{ => gui/xml}/folder_popup.xml | 0
src/{ => gui/xml}/menu.xml | 0
src/{ => gui/xml}/project_popup.xml | 0
src/utils.py | 667 -------
src/utils/Callbacks.py | 964 ++++++++++
src/utils/Callbacks.py.~1~ | 998 ++++++++++
src/{lib/decorators.py => utils/Decorators.py} | 37 +-
src/{dependencyloop.py => utils/DependencyLoop.py} | 33 +-
.../DependencyLoop.py.~1~} | 4 +-
src/utils/Helpers.py | 650 +++++++
src/utils/Helpers.py.~1~ | 385 ++++
src/utils/Icons.py | 169 ++
src/utils/Icons.py.~1~ | 169 ++
.../ProcessDependencyEvent.py} | 26 +-
.../ProcessDependencyEvent.py.~1~} | 20 +-
src/{project.py => utils/Project.py} | 14 +-
src/{settings.py => utils/Settings.py} | 2 +-
ChangeLog => src/utils/__init__.py | 0
38 files changed, 8742 insertions(+), 2254 deletions(-)
create mode 100755 gedamanager.py
create mode 100644 images/bitmaps/cog.png
create mode 100644 images/bitmaps/page_white_acrobat.png
delete mode 100644 images/bitmaps/page_white_error.png
create mode 100644 images/bitmaps/page_white_text.png
delete mode 100644 src/gedamanager.py
copy src/{gsch2pcb.py => gui/Gsch2pcb.py} (87%)
rename src/{gsch2pcb.py => gui/Gsch2pcb.py.~1~} (98%)
create mode 100644 src/gui/MainWindow.py
create mode 100644 src/gui/MainWindow.py.~1~
create mode 100644 src/gui/MainWindow.py.~2~
copy src/{newproject.py => gui/NewProject.py} (93%)
rename src/{newproject.py => gui/NewProject.py.~1~} (100%)
create mode 100644 src/gui/Preferences.py
create mode 100644 src/gui/Preferences.py.~1~
copy ChangeLog => src/gui/__init__.py (100%)
create mode 100644 src/gui/new.py.~1~
create mode 100644 src/gui/new.py.~2~
create mode 100644 src/gui/temp.py.~1~
rename src/{ => gui/xml}/file_popup.xml (100%)
rename src/{ => gui/xml}/folder_popup.xml (100%)
rename src/{ => gui/xml}/menu.xml (100%)
rename src/{ => gui/xml}/project_popup.xml (100%)
delete mode 100644 src/lib/__init__.py
delete mode 100644 src/utils.py
create mode 100644 src/utils/Callbacks.py
create mode 100644 src/utils/Callbacks.py.~1~
rename src/{lib/decorators.py => utils/Decorators.py} (70%)
copy src/{dependencyloop.py => utils/DependencyLoop.py} (75%)
rename src/{dependencyloop.py => utils/DependencyLoop.py.~1~} (97%)
create mode 100644 src/utils/Helpers.py
create mode 100644 src/utils/Helpers.py.~1~
create mode 100644 src/utils/Icons.py
create mode 100644 src/utils/Icons.py.~1~
copy src/{processdependencyevent.py => utils/ProcessDependencyEvent.py} (86%)
rename src/{processdependencyevent.py => utils/ProcessDependencyEvent.py.~1~} (88%)
rename src/{project.py => utils/Project.py} (91%)
rename src/{settings.py => utils/Settings.py} (99%)
copy ChangeLog => src/utils/__init__.py (100%)
=================
Commit Messages
=================
commit 0c9751236b273a4f68cd0d786ebbbc41be99f5ab
Author: Newell Jensen <jensen@xxxxxxxxxxxxxxxx>
Date: Sun Dec 21 21:12:33 2008 -0800
Made some major changes to the overall structure of the code.
Added some new icons, files, and logic.
:000000 100755 0000000... e1be46e... A gedamanager.py
:000000 100644 0000000... 67de2c6... A images/bitmaps/cog.png
:000000 100644 0000000... 8f8095e... A images/bitmaps/page_white_acrobat.png
:100644 000000 9fc5a0a... 0000000... D images/bitmaps/page_white_error.png
:000000 100644 0000000... 813f712... A images/bitmaps/page_white_text.png
:100644 000000 8488883... 0000000... D src/dependencyloop.py
:100644 000000 8ddac06... 0000000... D src/file_popup.xml
:100644 000000 7b74efe... 0000000... D src/folder_popup.xml
:100644 000000 a316753... 0000000... D src/gedamanager.py
:100644 000000 425c5d9... 0000000... D src/gsch2pcb.py
:000000 100644 0000000... c8a8092... A src/gui/Gsch2pcb.py
:000000 100644 0000000... 2b4f81b... A src/gui/Gsch2pcb.py.~1~
:000000 100644 0000000... 9c578b1... A src/gui/MainWindow.py
:000000 100644 0000000... c106bde... A src/gui/MainWindow.py.~1~
:000000 100644 0000000... 4959e04... A src/gui/MainWindow.py.~2~
:000000 100644 0000000... 6cd9bea... A src/gui/NewProject.py
:000000 100644 0000000... 31bd3a9... A src/gui/NewProject.py.~1~
:000000 100644 0000000... 2d423e9... A src/gui/Preferences.py
:000000 100644 0000000... 0b24519... A src/gui/Preferences.py.~1~
:000000 100644 0000000... e69de29... A src/gui/__init__.py
:000000 100644 0000000... 139597f... A src/gui/new.py.~1~
:000000 100644 0000000... bb6a595... A src/gui/new.py.~2~
:000000 100644 0000000... 8d1c8b6... A src/gui/temp.py.~1~
:000000 100644 0000000... 8ddac06... A src/gui/xml/file_popup.xml
:000000 100644 0000000... 7b74efe... A src/gui/xml/folder_popup.xml
:000000 100644 0000000... 9e4e0e5... A src/gui/xml/menu.xml
:000000 100644 0000000... ac7b532... A src/gui/xml/project_popup.xml
:100644 000000 e69de29... 0000000... D src/lib/__init__.py
:100644 000000 be858e0... 0000000... D src/lib/decorators.py
:100644 000000 9e4e0e5... 0000000... D src/menu.xml
:100644 000000 532d0d5... 0000000... D src/newproject.py
:100644 000000 2badf5b... 0000000... D src/processdependencyevent.py
:100644 000000 d1810c6... 0000000... D src/project.py
:100644 000000 ac7b532... 0000000... D src/project_popup.xml
:100644 000000 82723f0... 0000000... D src/settings.py
:100644 000000 541d0d2... 0000000... D src/utils.py
:000000 100644 0000000... 1d1d163... A src/utils/Callbacks.py
:000000 100644 0000000... ca4dac9... A src/utils/Callbacks.py.~1~
:000000 100644 0000000... 3546f34... A src/utils/Decorators.py
:000000 100644 0000000... f2485e9... A src/utils/DependencyLoop.py
:000000 100644 0000000... 66913f1... A src/utils/DependencyLoop.py.~1~
:000000 100644 0000000... ff5938e... A src/utils/Helpers.py
:000000 100644 0000000... fc301a5... A src/utils/Helpers.py.~1~
:000000 100644 0000000... bd032cf... A src/utils/Icons.py
:000000 100644 0000000... ea74fc5... A src/utils/Icons.py.~1~
:000000 100644 0000000... c2974d5... A src/utils/ProcessDependencyEvent.py
:000000 100644 0000000... ee9bb06... A src/utils/ProcessDependencyEvent.py.~1~
:000000 100644 0000000... 818a413... A src/utils/Project.py
:000000 100644 0000000... e40544a... A src/utils/Settings.py
:000000 100644 0000000... e69de29... A src/utils/__init__.py
=========
Changes
=========
commit 0c9751236b273a4f68cd0d786ebbbc41be99f5ab
Author: Newell Jensen <jensen@xxxxxxxxxxxxxxxx>
Date: Sun Dec 21 21:12:33 2008 -0800
Made some major changes to the overall structure of the code.
Added some new icons, files, and logic.
diff --git a/gedamanager.py b/gedamanager.py
new file mode 100755
index 0000000..e1be46e
--- /dev/null
+++ b/gedamanager.py
@@ -0,0 +1,38 @@
+#! /usr/bin/env python
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.gedamanager
+#The most Top Level entry point for gEDA Manager
+#@author Newell Jensen
+
+import gtk, pygtk, gobject
+from src.gui.MainWindow import MainWindow
+from threading import Thread
+gobject.threads_init()
+
+def main():
+ """ Function starts the main loop for gtk. """
+ gtk.main()
+
+if __name__ == "__main__":
+ window = MainWindow()
+ main()
+
diff --git a/images/bitmaps/cog.png b/images/bitmaps/cog.png
new file mode 100644
index 0000000..67de2c6
Binary files /dev/null and b/images/bitmaps/cog.png differ
diff --git a/images/bitmaps/page_white_acrobat.png b/images/bitmaps/page_white_acrobat.png
new file mode 100644
index 0000000..8f8095e
Binary files /dev/null and b/images/bitmaps/page_white_acrobat.png differ
diff --git a/images/bitmaps/page_white_error.png b/images/bitmaps/page_white_error.png
deleted file mode 100644
index 9fc5a0a..0000000
Binary files a/images/bitmaps/page_white_error.png and /dev/null differ
diff --git a/images/bitmaps/page_white_text.png b/images/bitmaps/page_white_text.png
new file mode 100644
index 0000000..813f712
Binary files /dev/null and b/images/bitmaps/page_white_text.png differ
diff --git a/src/dependencyloop.py b/src/dependencyloop.py
deleted file mode 100644
index 8488883..0000000
--- a/src/dependencyloop.py
+++ /dev/null
@@ -1,79 +0,0 @@
-"""
-gEDA Manager
-Copyright (C) 2008 Newell Jensen
-Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-"""
-
-##@package src.dependencyloop
-#Class to handle dependency loop for the project's sources.
-#@author Newell Jensen
-
-import gtk, pygtk
-pygtk.require('2.0')
-from pyinotify import *
-from processdependencyevent import *
-
-
-class DependencyLoop:
- """
- Class to handle the dependency loop for the project's sources.
- This class uses the python module pyinotify which is used to watch for
- filesystem changes. This is all run in a separate thread from the main
- execution thread and called as a seperate program in its own process.
- """
- def __init__(self, gedamanager):
- """!
- Constructor for the DependencyLoop class.
- This class is component of the gEDAManager class ('has-a' relationship).
- @param gedamanager current gEDAManager instance
- """
- # Things to do: (we can get all the info from the gedamanager object
- # Start the thread with the project's directory
- self.g = gedamanager
- self.watch_manager = WatchManager()
- self.processdependencyevent = ProcessDependencyEvent(self.g)
- self.threaded_notifier = ThreadedNotifier(self.watch_manager, self.processdependencyevent)
-
- self.threaded_notifier.start()
- # start watching the project's directory recursively
- self.wdd = None
- mask = IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO
- if self.g.project.directory != None:
- self.wdd = self.watch_manager.add_watch(self.g.project.directory, mask, rec=True)
-
-
- def switch_projects(self):
- """
- Method to switch which directory is being watched for events.
- This method will be called when projects are changed, etc.
- """
- # Takes care of subdirectories
- if self.wdd != None:
- self.watch_manager.rm_watch(self.wdd.values())
- # Now add a new watch to the new project
- mask = IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO
- if self.g.project.directory != None:
- self.wdd = self.watch_manager.add_watch(self.g.project.directory, mask, rec=True)
-
-
- def kill_thread(self):
- """
- Method to kill the DependencyLoop thread when gEDAManager exits.
- """
- self.threaded_notifier.stop()
-
-
diff --git a/src/file_popup.xml b/src/file_popup.xml
deleted file mode 100644
index 8ddac06..0000000
--- a/src/file_popup.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<ui>
- <popup>
- <separator/>
- <menuitem action="Open in Editor"/>
- <menuitem action="Rename"/>
- <menuitem action="Delete"/>
- <separator/>
- </popup>
-</ui>
diff --git a/src/folder_popup.xml b/src/folder_popup.xml
deleted file mode 100644
index 7b74efe..0000000
--- a/src/folder_popup.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<ui>
- <popup>
- <separator/>
- <menuitem action="New Source..."/>
- <menuitem action="New Folder"/>
- <menuitem action="Delete Folder"/>
- <menuitem action="Rename Folder"/>
- <menuitem action="Copy Existing Source To Project..."/>
- <separator/>
- </popup>
-</ui>
diff --git a/src/gedamanager.py b/src/gedamanager.py
deleted file mode 100644
index a316753..0000000
--- a/src/gedamanager.py
+++ /dev/null
@@ -1,1466 +0,0 @@
-#! /usr/bin/env python
-"""
-gEDA Manager
-Copyright (C) 2008 Newell Jensen
-Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-"""
-
-##@package src.gedamanager
-#Top-level window for the gEDA Manager
-#@author Newell Jensen
-
-import os, sys, gtk, pygtk, yaml, gnomevfs, time
-import gobject, shutil, vte, logging, subprocess
-pygtk.require('2.0')
-from lib.decorators import exceptions
-from project import *
-from settings import *
-from utils import *
-from newproject import *
-from dependencyloop import *
-from threading import Thread
-
-gobject.threads_init()
-
-class gEDAManager:
- """
- Top-level Window for the gEDA Manager.
- This class takes care of all window logic
- and communication with lower level objects.
- """
- def __init__(self):
- """ gEDAManager Constructor. """
-
- # Initialize gEDA Manager
-# self.depnum = 0
- self.no_project_name = 'No project loaded...\n\n Select:\n Project->Open Project\n or Project->New Project'
- self.settings = Settings()
- self.utils = Utils()
- if self.settings.project != None:
- self.project = Project(self.settings.project)
- else:
- self.project = Project()
- self.project.connect('closed', self.cb_project_closed)
- self.project.connect('saved', self.cb_project_saved)
- self.project.connect('opened', self.cb_project_opened)
- self.project.connect('created', self.cb_project_created)
- self.dependencyloop = DependencyLoop(self)
- # Create top-level window
- self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
- self.window.connect('destroy', self.cb_destroy)
- self.window.set_title('gEDA Manager')
- self.merge_id = 0
- # TODO create gEDA Manager icon
- self.window.set_icon_from_file('../images/icons/geda-xgsch2pcb-48.png')
- self.window.set_size_request(900,600)
- # Create a Menu UIManager and a Popup UIManager
- self.menu_uimanager = gtk.UIManager()
- self.popup_uimanager = gtk.UIManager()
- self.menu_accel_group = self.menu_uimanager.get_accel_group()
- self.window.add_accel_group(self.menu_accel_group)
- self.popup_accel_group = self.popup_uimanager.get_accel_group()
- self.__init_tools__()
- self.__init_menus__()
- self.__init_gui_sections__()
- self.__init_about_dialog__()
- self.set_menu_defaults()
- self.window.show()
-
-
- #####################################################
- # Initializer Methods -- methods to create the window
- #####################################################
-
- def __init_tools__(self):
- """
- Method to initialize attributes that will be used for the
- subprocess instances of the gEDA tools.
- """
- # More to be added
- self.tools = {'sch': None, 'pcb': None, 'gerbv': None, 'gattrib': None,
- 'editor': None}
- # Check if .gmrc has an editor attribute
- if self.settings.editor != None:
- self.tools['editor'] = self.settings.editor
-
-
- def __init_menus__(self):
- """ Method to create the menu bar. """
-
- actiongroup0 = gtk.ActionGroup('gEDAManager')
- actiongroup0_list = [('Project', None, '_Project'),
- ('New Project', None, 'Ne_w Project', None, 'Create New Project', self.cb_new_project),
- ('Open Project', None, 'Open P_roject', None, 'Open Existing Project', self.cb_open_project),
- ('Close Project', None, 'Close Projec_t', None, 'Close Active Project', self.cb_close_project),
- ('Exit', gtk.STOCK_QUIT, 'E_xit', '<Control>q', 'Exit gEDA Manager', self.cb_exit),
- ('Edit', None, '_Edit'),
- ('Preferences...', gtk.STOCK_PREFERENCES, 'Pr_eferences', None,
- 'gEDA Manager Preferences', self.cb_preferences),
- ('Help', None, '_Help'),
- ('gEDA Wiki', None, 'gEDA _Wiki', None, 'Opens link in browser',
- self.cb_url_geda_wiki),
- ('gEDA Documentation', None, 'gEDA _Documentation', None,
- 'Opens link in browser', self.cb_url_geda_documentation),
- ('gEDA Manager Documentation', None, 'gEDA _Manager Blog', None, 'Opens link in browser', self.cb_url_geda_manager_blog),
- ('gEDA Manager API Documentation', None, 'gEDA Manager _API Documentation', None, 'Opens link in browser', self.cb_url_geda_manager_api_documentation),
- ('Web Resources', None, '_Web Resources'),
- ('About', gtk.STOCK_ABOUT, '_About', None, 'Extra Information about gEDA and the gEDA Manager', self.cb_show_about_dialog),]
-
- actiongroup0.add_actions(actiongroup0_list)
- self.menu_uimanager.insert_action_group(actiongroup0, 0)
- merge_id = self.menu_uimanager.add_ui_from_file('menu.xml')
- menubar = self.menu_uimanager.get_widget('/MenuBar')
- self.vbox1 = gtk.VBox()
- self.vbox1.show()
- self.window.add(self.vbox1)
- self.vbox1.pack_start(menubar, False, False, 0)
-
- # Set up tooltips
- tooltips = gtk.Tooltips()
- widget = self.menu_uimanager.get_widget('/MenuBar/Project/New Project')
- action = self.menu_uimanager.get_action('/MenuBar/Project/New Project')
- tooltips.set_tip(widget, action.get_property('tooltip'))
- widget = self.menu_uimanager.get_widget('/MenuBar/Project/Open Project')
- action = self.menu_uimanager.get_action('/MenuBar/Project/Open Project')
- tooltips.set_tip(widget, action.get_property('tooltip'))
- widget = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
- action = self.menu_uimanager.get_action('/MenuBar/Project/Close Project')
- tooltips.set_tip(widget, action.get_property('tooltip'))
- widget = self.menu_uimanager.get_widget('/MenuBar/Project/Exit')
- action = self.menu_uimanager.get_action('/MenuBar/Project/Exit')
- tooltips.set_tip(widget, action.get_property('tooltip'))
- widget = self.menu_uimanager.get_widget('/MenuBar/Edit/Preferences...')
- action = self.menu_uimanager.get_action('/MenuBar/Edit/Preferences...')
- tooltips.set_tip(widget, action.get_property('tooltip'))
- widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Manager Documentation')
- action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Manager Documentation')
- tooltips.set_tip(widget, action.get_property('tooltip'))
- widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Documentation')
- action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Documentation')
- tooltips.set_tip(widget, action.get_property('tooltip'))
- widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Wiki')
- action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Wiki')
- tooltips.set_tip(widget, action.get_property('tooltip'))
- widget = self.menu_uimanager.get_widget('/MenuBar/Help/About')
- action = self.menu_uimanager.get_action('/MenuBar/Help/About')
- tooltips.set_tip(widget, action.get_property('tooltip'))
-
-
- def __init_gui_sections__(self):
- """ Method to create the main gui sections of the top-level window. """
- # Partitioning the window
- hpaned = gtk.HPaned()
- hpaned.set_position(400)
- self.vbox1.pack_start(hpaned, True, True, 0)
- hpaned.show()
-
- # Notebook
- vpaned = gtk.VPaned() # This is the vpaned for sources and process
- hpaned.pack1(vpaned, True, True)
- vpaned.show()
- sources_notebook = gtk.Notebook()
- sources_notebook.show()
- processes_notebook = gtk.Notebook()
- processes_notebook.show()
- sources_notebook.connect('switch-page', self.cb_switch_page)
- processes_notebook.connect('switch-page', self.cb_switch_page)
- vpaned.pack1(sources_notebook, True, True)
- vpaned.pack2(processes_notebook, True, True)
- sources_notebook.set_tab_pos(gtk.POS_BOTTOM)
- processes_notebook.set_tab_pos(gtk.POS_BOTTOM)
-
- scrolled_window_sources = gtk.ScrolledWindow()
- scrolled_window_sources.show()
- scrolled_window_processes = gtk.ScrolledWindow()
- scrolled_window_processes.show()
- scrolled_window_dependencies = gtk.ScrolledWindow()
- scrolled_window_dependencies.show()
- scrolled_window_sources.set_shadow_type(gtk.SHADOW_IN)
- scrolled_window_sources.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- scrolled_window_processes.set_shadow_type(gtk.SHADOW_IN)
- scrolled_window_processes.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- scrolled_window_dependencies.set_shadow_type(gtk.SHADOW_IN)
- scrolled_window_dependencies.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-
- sources_notebook.add(scrolled_window_sources)
- processes_notebook.add(scrolled_window_processes)
- sources_notebook.append_page(scrolled_window_dependencies)
-
- # Labels
- sources_label = gtk.Label('Sources')
- sources_label.show()
- dependencies_label = gtk.Label('Dependencies')
- dependencies_label.show()
- processes_label = gtk.Label('Processes')
- processes_label.show()
- sources_notebook.set_tab_label(sources_notebook.get_nth_page(0), sources_label)
- sources_notebook.set_tab_label(sources_notebook.get_nth_page(1), dependencies_label)
- processes_notebook.set_tab_label(processes_notebook.get_nth_page(0), processes_label)
-
- # Models for the Tree Views
- self.sources = gtk.TreeStore(gtk.gdk.Pixbuf, str, str)
- self.processes = gtk.TreeStore(str, gtk.gdk.Pixbuf, gtk.gdk.Pixbuf)
- self.dependencies = gtk.TreeStore(str, str)
-
- # Source Tree View
- self.sources_tree = gtk.TreeView(self.sources)
- self.sources_tree.show()
- self.sources_tree.connect('button_press_event', self.cb_button_press)
- self.sources_tree.connect('row-activated', self.utils.cb_sources_row_activated, self)
- self.sources_tree.connect('cursor-changed', self.cb_cursor_changed)
- column = gtk.TreeViewColumn(None, gtk.CellRendererPixbuf(), pixbuf=0)
- self.sources_tree.append_column(column)
- sources_cell = gtk.CellRendererText()
- column = gtk.TreeViewColumn(None, sources_cell, text=1)
- column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- self.sources_tree.append_column(column)
-
- # Processes Tree View
- self.processes_tree = gtk.TreeView(self.processes)
- self.processes_tree.show()
- self.processes_tree.connect('row-activated', self.utils.cb_processes_row_activated, self)
- column = gtk.TreeViewColumn('Processes for: ', gtk.CellRendererText(), text=0)
- column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- self.processes_tree.append_column(column)
- processes_pixbuf = gtk.CellRendererPixbuf()
- processes_pixbuf.set_property('xalign', 0.2)
- column = gtk.TreeViewColumn(None, processes_pixbuf, pixbuf=1)
- self.processes_tree.append_column(column)
- column = gtk.TreeViewColumn(None, processes_pixbuf, pixbuf=2)
- column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- self.processes_tree.append_column(column)
-
- # Dependencies Tree View
- self.dependencies_tree = gtk.TreeView(self.dependencies)
- self.dependencies_tree.show()
- self.dependencies.connect('row-changed', self.cb_row_changed)
-
- # create the TreeViewColumn to display the data
- column = gtk.TreeViewColumn('Files')
- column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- dependencies_cell = gtk.CellRendererText()
- column.pack_start(dependencies_cell, True)
- column.add_attribute(dependencies_cell, 'text', 0)
-
- # Allow sorting on the column
- column.set_sort_column_id(0)
- self.dependencies_tree.append_column(column)
-
- # enable-tree-lines
- self.sources_tree.set_property('enable-tree-lines', True)
- self.processes_tree.set_property('enable-tree-lines', True)
- self.dependencies_tree.set_property('enable-tree-lines', True)
-
- # make it searchable
- self.sources_tree.set_search_column(0)
- self.processes_tree.set_search_column(0)
- self.dependencies_tree.set_search_column(0)
-
- # Allow drag and drop reordering of rows
- self.dependencies_tree.set_reorderable(True)
- self.sources_tree.set_reorderable(True)
-
- # set tooltip columns
- self.sources_tree.set_tooltip_column(2)
- self.dependencies_tree.set_tooltip_column(1)
-
- # add to the scrolling windows
- scrolled_window_sources.add(self.sources_tree)
- scrolled_window_processes.add(self.processes_tree)
- scrolled_window_dependencies.add(self.dependencies_tree)
-
- ######################################
- # Lower Notebook Window
- ######################################
-
- notebook = gtk.Notebook()
- notebook.show()
- hpaned.pack2(notebook, True, True)
- notebook.set_tab_pos(gtk.POS_BOTTOM)
- terminal_scrolled_window = gtk.ScrolledWindow()
- terminal_scrolled_window.show()
-
- # Add a terminal to the terminal output notebook
- current_directory = os.getcwd()
- try:
- os.chdir(self.project.directory)
- except:
- pass
- self.terminal = vte.Terminal()
- self.terminal.connect('child-exited', lambda term: self.cb_vte())#lambda term: gtk.main_quit())
- self.terminal.fork_command()
- self.terminal.show()
- os.chdir(current_directory)
- terminal_scrolled_window.set_shadow_type(gtk.SHADOW_IN)
- terminal_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- terminal_scrolled_window.add_with_viewport(self.terminal)
- notebook.add(terminal_scrolled_window)
-
- icon = gtk.IconTheme()
- terminal_icon = icon.load_icon(self.utils.icon_lut['terminal'], 22, 0)
- terminal_pixbuf = gtk.Image()
- terminal_pixbuf.set_from_pixbuf(terminal_icon)
- notebook.set_tab_label(notebook.get_nth_page(0), terminal_pixbuf)
-
- output_scolled_window = gtk.ScrolledWindow()
- output_scolled_window.show()
- output_scolled_window.set_shadow_type(gtk.SHADOW_IN)
- output_scolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- notebook.add(output_scolled_window)
-
- output_textview = gtk.TextView()
- output_textview.set_editable(False)
- output_textview.set_cursor_visible(False)
- self.output_textbuffer = output_textview.get_buffer()
- self.output_textiter = self.output_textbuffer.get_start_iter()
- output_textview.show()
- output_scolled_window.add(output_textview)
-
- output_icon = icon.load_icon(self.utils.icon_lut['output'], 22, 0)
- output_pixbuf = gtk.Image()
- output_pixbuf.set_from_pixbuf(output_icon)
- notebook.set_tab_label(notebook.get_nth_page(1), output_pixbuf)
-
- errors_scrolled_window = gtk.ScrolledWindow()
- errors_scrolled_window.show()
- errors_scrolled_window.set_shadow_type(gtk.SHADOW_IN)
- errors_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- notebook.add(errors_scrolled_window)
-
- errors_textview = gtk.TextView()
- errors_textview.set_editable(False)
- errors_textview.set_cursor_visible(False)
- self.errors_textbuffer = errors_textview.get_buffer()
- self.errors_textiter = self.errors_textbuffer.get_start_iter()
- errors_textview.show()
- errors_scrolled_window.add(errors_textview)
-
- errors_icon = icon.load_icon(self.utils.icon_lut['errors'], 22, 0)
- errors_pixbuf = gtk.Image()
- errors_pixbuf.set_from_pixbuf(errors_icon)
- notebook.set_tab_label(notebook.get_nth_page(2), errors_pixbuf)
-
- self.output_textbuffer.insert(self.output_textiter, 'Output log--\n')
- self.errors_textbuffer.insert(self.errors_textiter, 'Error log--\n')
-
- # Finally add data to the sources_tree and the dependencies_tree
- self.set_sources_tree_to_project()
- self.set_dependencies_tree_to_project()
-
-
- def __init_about_dialog__(self):
- """ Method to create the about dialog. """
-
- def about_url_cb(dialog, link, user_data):
- """!
- Call back function to test url for the about dialog
- @param dialog about dialog object
- @param link url link that was clicked
- @param user_data user data that was passed in
- """
- gnomevfs.url_show(link)
-
- self.aboutdialog = gtk.AboutDialog()
- self.aboutdialog.set_name("gEDA Manager")
- self.aboutdialog.set_license(__doc__)
- self.aboutdialog.set_version(str(self.settings.version))
- self.aboutdialog.set_copyright("gEDA Manager 2008")
- self.aboutdialog.set_authors(['Newell Jensen', '--',
- 'Before Enlightenment, chop wood and carry water',
- 'After Enlightenment, code and build circuits'])
- gtk.about_dialog_set_url_hook(about_url_cb, None)
- self.aboutdialog.set_website('http://geda.seul.org')
- self.aboutdialog.set_translator_credits('translator-credits')
- self.aboutdialog.set_transient_for(self.window)
-
-
- ####################################
- # Methods
- ####################################
-
- def set_menu_defaults(self):
- """
- Method to coordiante which methods should be called to handle
- the sensitivity of the menu items.
- """
- # Project
- if self.project.name == None or self.project.name == self.no_project_name:
- self.set_no_project_default()
- else:
- self.set_project_default()
-
-
- def set_no_project_default(self):
- """
- Method to set the default sensitivity when no project is loaded.
- """
- # File Menu
- self.project.name = self.no_project_name
- self.sources_tree.set_property('headers-visible', True)
- column = self.sources_tree.get_column(0)
- column.set_title(self.project.name)
- save_project_as_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Save Project As...')
- close_project_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
- close_project_menuitem.set_sensitive(False)
-
-
- def set_project_default(self):
- """
- Method to set the default sensitivity when a project is loaded.
- """
- # File Menu
- self.sources_tree.set_property('headers-visible', False)
- save_project_as_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Save Project As...')
- close_project_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
- close_project_menuitem.set_sensitive(True)
-
-
- def set_project(self, path):
- """!
- Method to set current project to the one on path.
- @param path path for project to open.
- """
- # Save current project
- if not self.project.clean:
- self.project.save()
- self.project.open(path)
- self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project set to ' + self.project.name + '\n')
- self.dependencyloop.switch_projects()
-
-
- def set_sources_tree_to_project(self):
- """ Method to set the tree to current project object. """
- self.sources.clear()
- if self.project.name != None:
- self.load_sources_tree()
- self.sources_tree.expand_all()
-
-
- def set_dependencies_tree_to_project(self):
- """ Method to set the tree to current project object. """
- self.dependencies.clear()
- if self.project.dependency_list != None:
- self.load_dependencies_tree()
- self.dependencies_tree.expand_all()
-
-
- def set_dependencies_tree_to_new_project(self):
- """ Method to set the tree to newly created project object. """
- #self.dependencyloop.switch_projects()
- self.dependencies.clear()
- # Parent Folder
- project_path = self.project.directory + '/' + self.project.name
- project_file_path = project_path + '.gm'
- output_file_path = self.project.directory + '/output.log'
- error_file_path = self.project.directory + '/error.log'
-
-
- def load_sources_tree(self):
- """
- Method to the load the 'Sources' TreeView from the
- directory structure of the project.
- """
- if self.sources != None:
- # Clear out the sources first
- self.sources.clear()
- # Start adding data to the Model
- if isinstance(self.project.directory, str):
- if os.path.exists(self.project.directory):
- os.chdir(self.project.directory)
- node = None
- dictionary = {}
- icon = gtk.IconTheme() # The icon used throughout the function
- for root, dirs, files in os.walk(self.project.directory):
- if root == self.project.directory:
- image = icon.load_icon(self.utils.icon_lut['project'], 22, 0)
- else:
- image = icon.load_icon(self.utils.icon_lut['folder'], 22, 0)
-
- folder = root.split('/')[-1]
- try:
- node = self.sources.append(dictionary[root], [image, folder, root])
- except KeyError:
- node = self.sources.append(None, [image, folder, root])
- for f in [name for dec,name in sorted((os.path.splitext(f)[1][1:],f) for f in files)]: # List expression sorts by file extension
- if not f.endswith(('~','-','#')):
- image = icon.load_icon(self.utils.load_image(f), 22, 0)
- self.sources.append(node, [image, f, os.path.join(root, f)])
- for d in dirs:
- dictionary[os.path.join(root, d)] = node
-
- self.sources_tree.expand_all()
-
-
- def load_dependencies_tree(self):
- """!
- Method to the load the dependencies tree
- """
- # Need to add checking for whether or not the filesystem still
- # has the files before appending them to self.dependencies
-
- # Either this or have a function that I call before this one that
- # straightens it all out by going over the dependency_list and making
- # sure that these files are the correct ones and if not it can call
- # the functions remove/add/update_dependency() functions
- def recurse_dependencies(dep_list, parent):
- for value in dep_list:
- filename = self.utils.get_filename_from_filepath(value)
- n_parent = self.dependenices.append(parent, [filename, value])
- # recurse
- if self.project.dependency_list[value] != []:
- recurse_dependencies(self.project.dependency_list[value], n_parent)
-
- if self.dependencies != None:
- self.dependencies.clear()
- for key, value in self.project.dependency_list.iteritems():
- filename = self.utils.get_filename_from_filepath(key)
- n_parent = self.dependencies.append(None, [filename, key])
- # recurse
- if self.project.dependency_list[key] != []:
- recurse_dependencies(value, n_parent)
-
-
- def update_dependency(self, pathname, recurse=False):
- # First, make sure that the file is already in the dependencies
- if self.project.dependency_status != None:
- try:
- if not recurse:
- self.project.dependency_status[pathname] = True
- else:
- self.project.dependency_status[pathname] = False
- # recurse over the dependency_list
- if self.project.dependency_list != None:
- for value in self.project.dependency_list[pathname]:
- self.update_dependency(value, True)
- except KeyError:
- print 'KeyError_update'
- finally:
- self.project.save()
- self.load_dependencies_tree()
-
-
- def add_dependency(self, pathname):
- print 'in add_dependency'
- try:
- if self.project.dependency_list != None:
- self.project.dependency_list[pathname] = []
- if self.project.dependency_status != None:
- self.project.dependency_status[pathname] = True
- except KeyError:
- print 'KeyError_add'
- finally:
- self.project.save()
- self.load_dependencies_tree()
-
-
- def remove_dependency(self, pathname, recurse=False):
- # First, make sure that the file is already in the dependencies
- if self.project.dependency_status != None:
- if pathname in self.project.dependency_status:
- try:
- # iterate over the dependencies and flatten
- for value in self.project.dependency_list[pathname]:
- self.remove_dependency(value, True)
- self.project.dependency_list[pathname] = []
- except KeyError:
- print 'KeyError_remove'
- finally:
- if not recurse:
- del self.project.dependency_status[pathname]
- del self.project.dependency_list[pathname]
- else:
- self.project.dependency_status[pathname] = False
- self.project.save()
- self.load_dependencies_tree()
-
-
- def save_settings(self):
- """ Method to save current settings to .gmrc file. """
-
- if self.project.directory and self.project.name:
- self.settings.project = self.project.directory + '/' + self.project.name + '.gm'
- else:
- self.settings.project = None
- self.settings.create_config_file()
-
-
- def get_processes_selected_node(self):
- """!
- Method to get the selected node in the 'Processes' treeview.
- @return path of the selected node
- """
- selection = self.processes_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- return self.processes.get_value(selection_iter, 2)
- else:
- return None
-
-
- def file_filters(self, dialog):
- """!
- Method to abstract some redundant code that is used in the message
- dialog boxes.
- @param dialog gtk.FileChooserDialog object
- """
- # These are subject to change depending on users input
- # TODO -- see if we need these at all
- # also see if we can add multiple filters per name e.g. .vhd and .vhdl
- file_filter = gtk.FileFilter()
- file_filter.set_name("All files")
- file_filter.add_pattern('*')
- dialog.add_filter(file_filter)
-
- file_filter = gtk.FileFilter()
- file_filter.set_name("schematics (.sch)")
- file_filter.add_pattern('*.sch')
- dialog.add_filter(file_filter)
-
- file_filter = gtk.FileFilter()
- file_filter.set_name("symbols (.sym)")
- file_filter.add_pattern('*.sym')
- dialog.add_filter(file_filter)
-
- file_filter = gtk.FileFilter()
- file_filter.set_name("pcb (.pcb)")
- file_filter.add_pattern('*.pcb')
- dialog.add_filter(file_filter)
-
- file_filter = gtk.FileFilter()
- file_filter.set_name("verilog (.v)")
- file_filter.add_pattern('*.v')
- dialog.add_filter(file_filter)
-
- file_filter = gtk.FileFilter()
- file_filter.set_name("vhdl (.vhd)")
- file_filter.add_pattern('*.vhd')
- dialog.add_filter(file_filter)
-
- file_filter = gtk.FileFilter()
- file_filter.set_name("bom (.bom)")
- file_filter.add_pattern('*.bom')
- dialog.add_filter(file_filter)
-
- file_filter = gtk.FileFilter()
- file_filter.set_name("drc (.drc)")
- file_filter.add_pattern('*.drc')
- dialog.add_filter(file_filter)
-
- file_filter = gtk.FileFilter()
- file_filter.set_name("gerber (.gbr)")
- file_filter.add_pattern('*.gbr')
- dialog.add_filter(file_filter)
-
- file_filter = gtk.FileFilter()
- file_filter.set_name("spice (.spice)")
- file_filter.add_pattern('*.spice')
- dialog.add_filter(file_filter)
-
-
- @exceptions
- def write_logs(self):
- """
- Method to write out the error and output logs with what is in
- the textbuffers.
- """
- startiter, enditer = self.output_textbuffer.get_bounds()
- output = self.output_textbuffer.get_text(startiter, enditer)
- os.chdir(self.project.directory)
- f = file('output.log', 'a')
- f.writelines(output)
- f.close()
-
- startiter, enditer = self.errors_textbuffer.get_bounds()
- errors = self.errors_textbuffer.get_text(startiter, enditer)
- os.chdir(self.project.directory)
- f = file('error.log', 'a')
- f.writelines(errors)
- f.close()
-
-
- @exceptions
- def kill_processes(self):
- """
- Method to kill all the open processes if there are still any
- open when the gEDAManager is closed.
- """
- # TODO - if open processes's prompt the user to save work
- # before exiting
- # e.g.
- # "You have open processes. If you exit you may lose unsaved
- # changes. Would you like to proceed? Okay or Cancel.
- for tool, value in self.tools.iteritems():
- if value != None and not isinstance(value, str): # kill the process
- os.kill(value.pid, signal.SIGKILL)
-
-
- ######################################################
- # Callback Methods -- signal handlers are event driven
- ######################################################
-
- def cb_show_about_dialog(self, menuitem, data=None):
- """!
- Event handler for About menu button.
- @param menuitem about menuitem that threw the event
- @param data optional user data to pass in
- """
- self.aboutdialog.show()
- self.aboutdialog.run()
- self.aboutdialog.hide()
-
-
- def cb_url_geda_wiki(self, menuitem, data=None):
- """!
- Event handler for gEDA Wiki.
- @param menuitem menuitem that threw the event
- @param data optional user data to pass in
- """
- gnomevfs.url_show('http://geda.seul.org/wiki/')
-
-
- def cb_url_geda_documentation(self, menuitem, data=None):
- """!
- Event handler for gEDA Documentation.
- @param menuitem menuitem that threw the event
- @param data optional user data to pass in
- """
- gnomevfs.url_show('http://geda.seul.org/wiki/geda:documentation')
-
-
- def cb_url_geda_manager_blog(self, menuitem, data=None):
- """!
- Event handler for gEDA Manager.
- @param menuitem menuitem that threw the event
- @param data optional user data to pass in
- """
- gnomevfs.url_show('http://www.gempillar.com')
-
-
- def cb_url_geda_manager_api_documentation(self, menuitem, data=None):
- """!
- Event handler for gEDA Manager.
- @param menuitem menuitem that threw the event
- @param data optional user data to pass in
- """
- gnomevfs.url_show('http://www.gempillar.com/docs/geda-manager')
-
-
- def cb_new_project(self, menuitem, data=None):
- """!
- Event handler for 'New Project'.
- @param menuitem menuitem that threw the event
- @param data optional user data to pass in
- """
- self.project.save()
- NewProject(self)
-
-
- def cb_open_project(self, menuitem, data=None):
- """!
- Event handler for 'Open Project'.
- @param menuitem menuitem that threw the event
- @param data optional user data to pass in
- """
- self.project.save()
- dialog = gtk.FileChooserDialog('Open...',
- self.window,
- gtk.FILE_CHOOSER_ACTION_OPEN,
- (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
- gtk.STOCK_OPEN, gtk.RESPONSE_OK))
-
- dialog.set_default_response(gtk.RESPONSE_OK)
-
- file_filter = gtk.FileFilter()
- file_filter.set_name("Project files (*.gm)")
- file_filter.add_pattern('*.gm')
- dialog.add_filter(file_filter)
-
- response = dialog.run()
- if response == gtk.RESPONSE_OK:
- self.set_project(dialog.get_filename())
- dialog.destroy()
-
-
- def cb_close_project(self, menuitem, data=None):
- """!
- Event handler for 'Close Project'.
- @param menuitem menuitem that threw the event
- @param data optional user data to pass in
- """
- self.write_logs()
- self.project.save()
- self.project.close()
- # clear the processes window
- self.processes.clear()
-
-
- def cb_project_closed(self, widget, event):
- """!
- Event occurs when a Project object is closed
- @param widget widget that threw the event
- @param event event that was thrown
- """
- self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project closed.\n')
- self.set_menu_defaults()
- self.set_sources_tree_to_project()
- self.set_dependencies_tree_to_project()
-
-
- def cb_project_saved(self, widget, event):
- """!
- Event occurs when a Project object is saved.
- @param widget widget that threw the event
- @param event event that was thrown
- """
- if self.project.name != None:
- self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project ' + self.project.name + ' saved.\n')
- else:
- self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project saved.\n')
- self.set_menu_defaults()
-
-
- def cb_project_opened(self, widget, event):
- """!
- Event occurs when a Project object is opened
- @param widget widget that threw the event
- @param event event that was thrown
- """
- self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project ' + self.project.name + ' opened.\n')
- self.set_menu_defaults()
- self.set_sources_tree_to_project()
- self.set_dependencies_tree_to_project()
-
-
- def cb_project_created(self, widget, event):
- """!
- Event occurs when a Project object is created
- @param widget widget that threw the event
- @param event event that was thrown
- """
- self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nProject ' + self.project.name + ' created.\n')
- self.set_menu_defaults()
- self.set_sources_tree_to_project()
- self.set_dependencies_tree_to_new_project()
-
-
- @exceptions
- def cb_preferences(self, menuitem, data=None):
- """!
- Event occurs when the user opens up the preferences menu.
- @param menuitem menuitem that threw the event
- @param data optional user data to pass in
- """
- def new_source_cursor_changed(newsources_tree):
- selection = newsources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- self.newsource = model.get_value(selection_iter, 1)
-
- if self.settings.editor != None:
- old_editor = self.settings.editor
- else:
- old_editor = None
-
- def response_to_dialog(entry, dialog, response):
- dialog.response(response)
-
- entry = gtk.Entry()
- if self.settings.editor != None:
- entry.set_text(self.settings.editor)
- entry.show()
-
- def cb_filebutton_selection_changed(filechooser, entry):
- self.settings.editor = filebutton.get_filename()
- entry.delete_text(0,-1)
- entry.set_text(self.settings.editor)
-
- dialog = gtk.MessageDialog(self.window,
- (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
- gtk.MESSAGE_OTHER,
- gtk.BUTTONS_OK_CANCEL,
- gtk.STOCK_DIRECTORY)
- dialog.set_markup('<b>Preference settings:</b>')
- dialog.set_title('Preferences')
- hbox = gtk.HBox()
- hbox.show()
-
- filebutton = gtk.FileChooserButton('Text Editor')
- filebutton.show()
- filebutton.connect('selection-changed',
- cb_filebutton_selection_changed, entry)
- filebutton.set_local_only(True)
- filebutton.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
- hbox.pack_end(filebutton)
-
- entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
- hbox.pack_end(entry)
- label = gtk.Label('Text Editor:')
- label.show()
- hbox.pack_end(label)
-
- dialog.vbox.pack_end(hbox, True, True, 0)
- dialog.show()
- dialog.run()
- if old_editor != self.settings.editor: # A change was made
- new_text = self.settings.editor
- else:
- new_text = entry.get_text()
- dialog.destroy()
-
- if new_text:
- self.settings.editor = new_text
-
-
- @exceptions
- def cb_new_source(self, menuitem, data=None):
- """!
- Event occurs when the user wants to add a source to the project
- @param menuitem menutiem that threw the event
- @param data optional user data to pass in
- """
- def new_source_cursor_changed(newsources_tree):
- selection = newsources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- self.newsource = model.get_value(selection_iter, 1)
- else:
- self.newsource = None
-
- def response_to_dialog(entry, dialog, response):
- dialog.response(response)
-
-
- dialog = gtk.MessageDialog(self.window,
- (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
- gtk.MESSAGE_QUESTION,
- gtk.BUTTONS_OK_CANCEL,
- gtk.STOCK_DIRECTORY)
- dialog.set_markup('<b>Please enter the new file name (extension will be added):</b>')#\n(add extension to override defaults):</b>')
- entry = gtk.Entry()
- entry.show()
- entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
- hbox = gtk.HBox()
- hbox.show()
- hbox.pack_end(entry)
- label = gtk.Label('File name:')
- label.show()
- hbox.pack_end(label)
-
- # Models for the Tree View
- newsources = gtk.TreeStore(gtk.gdk.Pixbuf, str)
- # Tree View
- newsources_tree = gtk.TreeView(newsources)
- newsources_tree.show()
- newsources_tree.connect('cursor-changed', new_source_cursor_changed)
- # column headings
- newsources_pixbuf = gtk.CellRendererPixbuf()
- newsources_pixbuf.set_property('xalign', 0)
- column = gtk.TreeViewColumn(None, newsources_pixbuf, pixbuf=0)
- newsources_tree.append_column(column)
- newsources_cell = gtk.CellRendererText()
- column = gtk.TreeViewColumn('Source Type', newsources_cell, text=1)
- column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- newsources_tree.append_column(column)
- # populate the tree view
- icon = gtk.IconTheme()
- image = icon.load_icon(self.utils.icon_lut['pcb'], 22, 0)
- newsources.append(None, [image, 'PCB (.pcb)'])
- image = icon.load_icon(self.utils.icon_lut['sch'], 22, 0)
- newsources.append(None, [image, 'Schematic (.sch)'])
- image = icon.load_icon(self.utils.icon_lut['v'], 22, 0)
- newsources.append(None, [image, 'Verilog (.v)'])
- image = icon.load_icon(self.utils.icon_lut['vhd'], 22, 0)
- newsources.append(None, [image, 'VHDL (.vhd)'])
- image = icon.load_icon(self.utils.icon_lut['sym'], 22, 0)
- newsources.append(None, [image, 'Symbol (.sym)'])
-
- # add to the hbox
- hbox.pack_start(newsources_tree, False, False)
- dialog.vbox.pack_end(hbox, True, True, 0)
-
- dialog.show()
- dialog.run()
- new_text = entry.get_text()
- dialog.destroy()
-
- if new_text and self.newsource != None:
- # Get the selected_node for the folder to add to
- selection = self.sources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- selected_node = self.sources.get_value(selection_iter, 2)
- # Get the type of extension for the program to call
- if '.' in new_text: # user may have overriden extension
- return
- else: # Need to find out what extension from the highlighted node
- ext = self.newsource[self.newsource.find('.')+1:self.newsource.find(')')]
- # Make sure a file with the same name doesn't already exist
- filepath = selected_node + '/' + new_text + '.' + ext
- filename = new_text + '.' + ext
- self.utils.update_file_list(self, 1, filepath)
- self.utils.run_command(self, filepath, None, ext)
- else:
- dialog = gtk.MessageDialog(self.window,
- (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
- gtk.MESSAGE_INFO,
- gtk.BUTTONS_OK,
- gtk.STOCK_DIRECTORY)
- dialog.set_markup('<b>Please enter text and/or make sure a file type is selected.</b>')
- dialog.show()
- response = dialog.run()
- dialog.destroy()
-
-
- @exceptions
- def cb_add_copy_source(self, menuitem, data=None):
- """!
- Event occurs when the user wants to add a source to the project
- @param menuitem menuitem that threw the event
- @param data optional user data to pass in
- """
- dialog = gtk.FileChooserDialog('Copy Existing Source To Project...',
- self.window,
- gtk.FILE_CHOOSER_ACTION_OPEN,
- (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
- gtk.STOCK_OPEN, gtk.RESPONSE_OK))
-
- dialog.set_default_response(gtk.RESPONSE_OK)
- self.file_filters(dialog)
- response = dialog.run()
- if response == gtk.RESPONSE_OK:
- filepath = dialog.get_filename()
- self.utils.update_file_list(self, 0, filepath)
- dialog.destroy()
-
-
- @exceptions
- def cb_new_folder(self, action):
- """!
- Event occurs when the user chooses to add a new folder to the project.
- @param action gtk.Action object
- """
- def response_to_dialog(entry, dialog, response):
- dialog.response(response)
-
- selection = self.sources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- selected_node = self.sources.get_value(selection_iter, 2)
- if '.' in selected_node:
- # This is not a folder
- # YES, this is a hack and was put in place because
- # we get some problems if the use right clicks on a node before
- # it becomes highlighted.
- return
- os.chdir(selected_node)
- dialog = gtk.MessageDialog(self.window,
- (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
- gtk.MESSAGE_QUESTION,
- gtk.BUTTONS_OK_CANCEL,
- gtk.STOCK_DIRECTORY)
- dialog.set_markup('<b>Please enter new folder name:</b>\nIf the folder name you choose exists\non disk in this directory it will deleted.')
- entry = gtk.Entry()
- entry.show()
- entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
- hbox = gtk.HBox()
- hbox.show()
- hbox.pack_end(entry)
- dialog.vbox.pack_end(hbox, True, True, 0)
- dialog.show()
- response = dialog.run()
- text = entry.get_text()
- if response == gtk.RESPONSE_OK and text.strip() != '':
- filepath = selected_node + '/' + text
-
- def delete_dependency_list_entry(arg, dirname, filenames):
- """ function to delete the filenames from the dependency_list """
- for f in filenames:
- print 'looking to delete dependency'
- if f in self.project.dependency_list and list(self.utils.flatten(self.project.file_list)).count(f) == 1:
- print 'deleting dependency'
- del self.project.dependency_list[f]
-
- # See if this directory already exists
- if os.path.exists(filepath): # delete directory recursively
- os.path.walk(filepath, delete_dependency_list_entry, None)
- shutil.rmtree(filepath)
- flag = True
- i = 0
- while flag:
- child_iter = self.sources.iter_nth_child(selection_iter, i)
- if child_iter != None:
- child_node = self.sources.get_value(child_iter, 2)
- if child_node == filepath:
- flag = self.sources.remove(child_iter)
- if flag: # break out if flag is true
- flag = False
- else:
- break
- i = i + 1
- os.mkdir(filepath)
- dialog.destroy()
-
-
- @exceptions
- def cb_delete(self, menuitem, data=None):
- """!
- Event handler for 'Delete'. This method will delete the file from the
- filesystem.
- @param menuitem that threw the event.
- @param data optional to pass in.
- """
- selection = self.sources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- selected_node = self.sources.get_value(selection_iter, 2)
- os.system('rm ' + selected_node)
- self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nDeleted ' + selected_node + '.\n')
-
-
- @exceptions
- def cb_delete_folder(self, widget):
- """!
- Event occurs when the user chooses to delete a folder from the project.
- This method will delete the folder from the filesystem.
- @param widget that threw the event.
- """
- selection = self.sources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- selected_node = self.sources.get_value(selection_iter, 2)
- exists = os.path.exists(selected_node)
- if exists: # delete directory recursively
- os.system('rm -rf ' + selected_node)
- self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nDeleted ' + selected_node + '.\n')
-
-
- @exceptions
- def cb_open_in_editor(self, action):
- """!
- Event occurs when the user wants to open a source file in the editor.
- @param action gtk.Action object involved with this event
- """
- selection = self.sources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- selected_node = self.sources.get_value(selection_iter, 2)
- # Run the command as if the file is a text file
- self.utils.run_command(self, selected_node, None, 'txt')
-
-
- @exceptions
- def cb_rename_folder(self, action):
- """!
- Event handler for renaming a folder.
- @param action gtk.Action object involved with this event
- """
- def response_to_dialog(entry, dialog, response):
- dialog.response(response)
-
- selection = self.sources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- old_path = self.sources.get_value(selection_iter, 2)
- path = self.sources.get_path(selection_iter)
-
- dialog = gtk.MessageDialog(self.window,
- (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
- gtk.MESSAGE_QUESTION,
- gtk.BUTTONS_OK_CANCEL,
- gtk.STOCK_DIRECTORY)
- dialog.set_markup('<b>Please enter the new folder name:\n</b>')
- entry = gtk.Entry()
- entry.show()
- entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
- hbox = gtk.HBox()
- hbox.show()
- hbox.pack_end(entry)
- dialog.vbox.pack_end(hbox, True, True, 0)
- dialog.show()
- dialog.run()
- new_text = entry.get_text()
- dialog.destroy()
- new_path = old_path.rpartition('/')[0] + '/' + new_text
-
- if '.' not in new_text:
- ## We are going to handle the project folder in cb_rename_folder
- if old_path == self.project.directory:
- # Project Folder
- os.rename(old_path, new_path)
- project_file = new_path + '/' + self.project.name + '.gm'
- os.remove(project_file)
- self.project.directory = new_path
- self.project.name = new_text
- ## self.project.file_list[0] = new_text
- ## self.project.file_list[1][0] = new_text + '.gm'
- self.project.save()
- self.output_textbuffer.insert(self.output_textiter, 'Project changed from ' + old_path + ' to ' + new_path + '.\n')
- else:
- # Regular folder
- if os.path.exists(new_path):
- self.output_textbuffer.insert(self.output_textiter, 'Folder already exists with this name. Cannot rename.\n')
- return
- os.rename(old_path, new_path)
-
-
- @exceptions
- def cb_rename(self, action):
- """!
- Event handler for renaming a file.
- @param action gtk.Action object involved with this event
- """
- def response_to_dialog(entry, dialog, response):
- dialog.response(response)
-
- selection = self.sources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- old_path = self.sources.get_value(selection_iter, 2)
- path = self.sources.get_path(selection_iter)
-
- dialog = gtk.MessageDialog(self.window,
- (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
- gtk.MESSAGE_QUESTION,
- gtk.BUTTONS_OK_CANCEL,
- gtk.STOCK_DIRECTORY)
- dialog.set_markup('<b>Please enter the new name\n(including extension if applicable):</b>')
- entry = gtk.Entry()
- entry.show()
- entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
- hbox = gtk.HBox()
- hbox.show()
- hbox.pack_end(entry)
- dialog.vbox.pack_end(hbox, True, True, 0)
- dialog.show()
- dialog.run()
- new_text = entry.get_text()
- dialog.destroy()
- new_path = old_path.rpartition('/')[0] + '/' + new_text
-
- if '.' in new_text and '.' in old_path:
- # File
- os.rename(old_path, new_path)
- self.output_textbuffer.insert(self.output_textiter, old_path + ' changed to ' + new_path + '.\n')
- elif not '.' in new_text and not '.' in old_path:
- # Folder -- so image does not need to be changed
- if os.path.exists(new_path):
- self.output_textbuffer.insert(self.output_textiter, 'Folder already exists with this name. Cannot rename.\n')
- return
- os.rename(old_path, new_path)
- self.output_textbuffer.insert(self.output_textiter, old_path + ' changed to ' + new_path + '.\n')
-
-
- @exceptions
- def cb_cursor_changed(self, widget):
- """!
- Event occurs when the cursor changes in the treeview.
- @param widget widget that threw the event
- """
- selection = self.sources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- selected_node = self.sources.get_value(selection_iter, 2)
- filename = self.utils.get_filename_from_filepath(selected_node)
- if '.' in filename and not filename.endswith(('.gm','.log')):
- # Logic to call function to find what type of file it is
- # and then to populate the according tree view
- ext = filename.split('.')[-1]
- self.utils.get_processes_tree(self, selected_node, ext, None, True)
- # Update 'Processes: ' for the 'Processes' tree
- column = self.processes_tree.get_column(0)
- column.set_title('Processes for: ' + filename)
- column = self.processes_tree.get_column(2)
- column.set_title('status')
- else: # We have the project folder
- # Clear out the columns
- column = self.processes_tree.get_column(0)
- column.set_title('')
- column = self.processes_tree.get_column(2)
- column.set_title('')
- # clear out the processes
- self.processes.clear()
-
-
- def cb_row_changed(self, model, path, iter):
- """!
- Event occurs when the columns change in the dependencies treeview.
- @param model gtk.TreeStore model for the dependencies
- """
- print 'starting cb_row_changed'
- # We only want a file to appear once
- def recurse_model(row_iter, row):
- try:
- for new_row in row_iter:
- if new_row[1] not in files:
- # new_dep_list[new_row[1]] = []
- new_dep_list[row[1]].append(new_row[1])
- files.append(new_row[1])
- new_row_iter = new_row.iterchildren()
- if new_row_iter != None:
- recurse_model(new_row_iter, new_row)
- except StopIteration:
- print 'StopIteraion'
- except:
- print 'except:', sys.exc_info()[0]
-
- files = []
- new_dep_list = {}
- for row in model:
- if row[1] not in files:
- new_dep_list[row[1]] = []
- files.append(row[1])
- row_iter = row.iterchildren()
- if row_iter != None:
- recurse_model(row_iter, row)
-
-
- print 'files:',files
- print 'new_dep_list:',new_dep_list
- self.project.dependency_list = new_dep_list
-
-
- @exceptions
- def cb_switch_page(self, notebook, page, page_num):
- if page_num == 1: # Dependencies notebook tab
- selection = self.sources_tree.get_selection()
- selection.unselect_all()
- self.processes.clear()
- column = self.processes_tree.get_column(0)
- column.set_title('')
- column = self.processes_tree.get_column(2)
- column.set_title('')
-
-
- @exceptions
- def cb_popup_deactivate(self, popup_menu, merge_id):
- """!
- Event occurs when the 'deactivate' signal is thrown from
- the popup menu.
- @param popup_menu is the popup_menu.
- @param merge_id is the merge id from the popup uimanager.
- """
- # Remove the ui from the uimanager
- self.popup_uimanager.remove_ui(merge_id)
-
-
- @exceptions
- def cb_button_press(self, widget, event):
- """!
- This signal handler will be called when the treeview emits
- a 'button_press_event' signal.
- @param widget widget that threw the event
- @param event event that was thrown
- """
- if event.button == 3:
- selection = self.sources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- selected_node = self.sources.get_value(selection_iter, 2)
- else:
- return
- popup_menu = gtk.Menu()
- actiongroup = gtk.ActionGroup('Popup')
- actiongroup_list = [('Rename', None, '_Rename', None, None, self.cb_rename),
- ('Rename Folder', None, '_Rename Folder', None, None, self.cb_rename_folder),
- ('Open in Editor', None, '_Open in Editor', None, None, self.cb_open_in_editor),
- ('New Source...', gtk.STOCK_FILE, '_New Source...', None, None, self.cb_new_source),
- ('Copy Existing Source To Project...', gtk.STOCK_COPY, '_Copy Existing Source To Project...', None, None, self.cb_add_copy_source),
- ('New Folder', gtk.STOCK_DIRECTORY, 'New _Folder', None, None, self.cb_new_folder),
- ('Delete', gtk.STOCK_DELETE, '_Delete', '<Control>d', None, self.cb_delete),
- ('Delete Folder', gtk.STOCK_DELETE, '_Delete Folder', None, None, self.cb_delete_folder),]
-
-
- actiongroup.add_actions(actiongroup_list)
- self.popup_uimanager.insert_action_group(actiongroup, 0)
-
- # Choose Popup Menu
- if selected_node == self.project.directory:
- # Project Folder
- merge_id = self.popup_uimanager.add_ui_from_file(self.utils.directory + '/project_popup.xml')
- popup_menu = self.popup_uimanager.get_widget('/popup')
- elif '.' not in selected_node:
- # Folder
- merge_id = self.popup_uimanager.add_ui_from_file(self.utils.directory + '/folder_popup.xml')
- popup_menu = self.popup_uimanager.get_widget('/popup')
- else:
- # File
- if selected_node.endswith('.gm'):
- return
- merge_id = self.popup_uimanager.add_ui_from_file(self.utils.directory + '/file_popup.xml')
- popup_menu = self.popup_uimanager.get_widget('/popup')
-
- popup_menu.connect('deactivate', self.cb_popup_deactivate, merge_id)
- popup_menu.show()
- popup_menu.popup(None, None, None, event.button, event.time)
-
-
- ## TODO -- combine the next three callbacks in some fashion
- def cb_exit(self, menuitem, data=None):
- """!
- Event handler for 'Exit'.
- @param menuitem menuitem that threw the event
- @param data optional user data to pass in
- """
- self.dependencyloop.kill_thread()
- self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nExiting gEDA Manager.\n')
- self.write_logs()
- self.dependencies.emit('row-changed', None, None)
- self.project.save()
- self.save_settings()
- self.kill_processes()
- gtk.main_quit()
-
-
- def cb_vte(self):
- """
- Event handler for when the embedded terminal is exited.
- """
- self.dependencyloop.kill_thread()
- self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nExiting gEDA Manager.\n')
- self.write_logs()
- self.dependencies.emit('row-changed', None, None)
- self.project.save()
- self.save_settings()
- self.kill_processes()
- gtk.main_quit()
-
-
- def cb_destroy(self, event):
- """!
- Event handlder when the form is closed in any fashion.
- @param event event that was thrown
- """
- self.dependencyloop.kill_thread()
- self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nExiting gEDA Manager.\n')
- self.write_logs()
- self.dependencies.emit('row-changed', None, None)
- self.project.save()
- self.save_settings()
- self.kill_processes()
- gtk.main_quit()
-
- ########################################################
-
- def main(self):
- """ Method starts the main loop for gtk. """
- gtk.main()
-
-
-if __name__ == "__main__":
- geda_manager = gEDAManager()
- geda_manager.main()
-
diff --git a/src/gsch2pcb.py b/src/gsch2pcb.py
deleted file mode 100644
index 425c5d9..0000000
--- a/src/gsch2pcb.py
+++ /dev/null
@@ -1,293 +0,0 @@
-"""
-gEDA Manager
-Copyright (C) 2008 Newell Jensen
-Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-"""
-
-##@package src.gsch2pcb
-#Gui for gsch2pcb workflow
-#@author Newell Jensen
-
-import os, pygtk, gtk
-pygtk.require('2.0')
-from lib.decorators import exceptions
-from subprocess import Popen, PIPE
-
-
-class Gsch2pcb:
- """
- Message Dialog for the gsch2pcb workflow.
- This class allows the user to select multiple schematics
- to be used in the gsch2pcb workflow to produce a PCB file.
- """
- def __init__(self, gedamanager, filepath):
- """!
- Gsch2pcb Constructor.
- @param gedamanagercurrent gEDAManager instance
- @param filepath filepath of file to be automatically included
- in the checklist of schematics
- """
- self.g = gedamanager
- def response_to_dialog_directory(entry, dialog, response):
- dialog.response(response)
-
- def response_to_dialog_name(entry, dialog, response):
- dialog.response(response)
-
- def response_to_dialog_project(entry, dialog, response):
- dialog.response(response)
-
- def cb_directory_selection_changed(filechooser, directory_entry):
- self.directory = self.filebutton.get_filename()
- directory_entry.set_text(self.directory)
-
- def cb_project_selection_changed(filechooser, project_entry):
- self.projectpath = self.projectfile.get_filename()
- self.project_entry.set_text(self.projectpath)
-
-
- self.dialog = gtk.MessageDialog(self.g.window,
- (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
- gtk.MESSAGE_OTHER,
- gtk.BUTTONS_OK_CANCEL,
- gtk.STOCK_DIRECTORY)
- self.dialog.set_markup('<b>Select one of the options below:</b>')
- self.dialog.set_title('gsch2pcb workflow')
-
- # Target Directory
- hbox = gtk.HBox()
- hbox.show()
- directory_entry = gtk.Entry()
- directory_entry.set_text(os.getcwd())
- directory_entry.show()
- directory_entry.connect('activate', response_to_dialog_directory, self.dialog, gtk.RESPONSE_OK)
- self.filebutton = gtk.FileChooserButton('Target Directory')
- self.filebutton.show()
- self.filebutton.connect('selection-changed',
- cb_directory_selection_changed, directory_entry)
- self.filebutton.set_local_only(True)
- self.filebutton.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
- hbox.pack_end(self.filebutton)
- hbox.pack_end(directory_entry)
- label = gtk.Label('Target Directory:')
- label.show()
- hbox.pack_end(label)
- self.dialog.vbox.pack_end(hbox, True, True, 0)
-
- # PCB name
- hbox = gtk.HBox()
- hbox.show()
- self.name_entry = gtk.Entry()
- self.name_entry.show()
- self.name_entry.connect('activate', response_to_dialog_name, self.dialog, gtk.RESPONSE_OK)
- hbox.pack_end(self.name_entry)
- label = gtk.Label('PCB Name (extension will be provided):')
- label.show()
- hbox.pack_end(label)
- self.dialog.vbox.pack_end(hbox, True, True, 0)
-
- # Schematic selections
- scrolled_window = gtk.ScrolledWindow()
- scrolled_window.show()
- scrolled_window.set_shadow_type(gtk.SHADOW_IN)
- scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- # Get schematics in project no matter what directory
- # They must be listed in the sources tree view though
- self.schematics = self.get_schematics()
- self.schematics_tree = gtk.TreeView(self.schematics)
- self.schematics_tree.show()
- column = gtk.TreeViewColumn('File', gtk.CellRendererText(), text=1)
- self.schematics_tree.append_column(column)
- toggle = gtk.CellRendererToggle()
- toggle.set_property('activatable', True)
- toggle.connect('toggled', self.cb_file_toggled, self.schematics)
- column = gtk.TreeViewColumn('Include', toggle)
- column.add_attribute(toggle, 'active', 2)
- self.schematics_tree.append_column(column)
- scrolled_window.add(self.schematics_tree)
- self.dialog.vbox.pack_end(scrolled_window, True, True, 0)
- self.dialog.show()
-
- response = self.dialog.run()
- if response == gtk.RESPONSE_OK:
- message = ''
- schematics_list = []
- schematics = ''
- self.in_project = False
-
- # Iterate over the gtk.TreeModel to create an arg input for gsch2pcb
- for row in self.schematics:
- if row[2]:
- # Add the schematic to the schematic_list
- schematics_list.append(row[1])
- schematics += row[1] + ' '
- if not schematics_list:
- message = 'At least one schematic must be chosen.\n'
- name = self.name_entry.get_text()
- if name == '' or name == None:
- message += 'A name for the PCB must be specified.\n'
- self.directory = directory_entry.get_text()
- if self.directory == '' or self.directory == None:
- message += 'A target directory must be chosen.\n'
- else:
- # Check to see if the target directory is in the project
- # If so, set in_project flag to true
- os.path.walk(self.directory, self.directory_match, None)
-
- if message != '':
- msg = message.rpartition('\n')[0]
- dm = gtk.MessageDialog(self.g.window,
- (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
- gtk.MESSAGE_INFO,
- gtk.BUTTONS_OK,
- gtk.STOCK_DIRECTORY)
- dm.set_markup(msg)
- dm.show()
- dm.run()
- dm.destroy()
- else:
- os.chdir(self.directory)
- files_before = os.listdir(self.directory)
- subproc = Popen(['gsch2pcb', '-v','-v','-o',name,schematics], stdout=PIPE).wait()
- ## print 'subproc:',subproc
- ## print 'subproc.communicate()[0]:',subproc.communicate()[0]
- ## self.g.output_textbuffer.insert(self.g.output_textiter, self.g.utils.get_time() + ' and output from gsch2pcb:\n' + subproc.communicate()[0] + '.\n')
-
- print 'self.directory:',self.directory
- print 'pwd:',os.getcwd()
- files_after = os.listdir(self.directory)
- files = []
- for f in files_after:
- if f not in files_before:
- files.append(f)
-
- ## if self.in_project:
- ## # Add it to the sources tree view
- ## icon = gtk.IconTheme()
- ## selection = self.g.sources_tree.get_selection()
- ## model, selection_iter = selection.get_selected()
-
- ## if isinstance(selection_iter, gtk.TreeIter):
- ## parent_iter = self.g.sources.iter_parent(selection_iter)
- ## else:
- ## print model
- ## print selection_iter
- ## ## wanted = ['pcb','new.pcb','net']
- ## ## new_files = []
- ## ## new_files.append(True)
- ## ## print 'files:',files
- ## ## print 'parent_iter:',parent_iter
- ## ## for f in files:
- ## ## if f.endswith('new.pcb'):
- ## ## ext = 'new.pcb'
- ## ## else:
- ## ## ext = f.split('.')[-1]
- ## ## if ext in wanted:
- ## ## filepath = self.directory + '/' + f
- ## ## print 'filepath:',filepath
- ## ## image = icon.load_icon(self.g.utils.icon_lut[ext], 22, 0)
- ## ## self.g.sources.append(parent_iter, [image, f, filepath])
- ## ## self.g.dependencies.append(None, [f, filepath])
- ## ## # add new file to the dependency_dict
- ## ## if f not in self.g.project.dependency_dict:
- ## ## self.g.project.dependency_dict[f] = [True]
- ## ## new_files.append(f)
- ## ## for sch in self.schematics:
- ## ## if sch[0] not in self.g.project.dependency_dict[sch[0]]:
- ## ## self.g.project.dependency_dict[sch[0]] = new_files
- ## ## else:
- ## ## self.g.project.dependency_dict[sch[0]][0] = True
- ## ## for f in new_files:
- ## ## self.g.project.dependency_dict[sch[0]].append(f)
- ## ## # Update the project and its file list
- ## ## self.g.utils.update_file_list(self.g)
- ## else:
- ## pass
- self.dialog.destroy()
-
-
- def directory_match(self, arg, dirname, filenames):
- """!
- Method to see whether or not the chosen directory for the gsch2pcb
- workflow is in the project directory structure or not.
- @param arg not used (needs to be here for the os.path.walk function)
- @param dirname name of current directory
- @param filenames list of file names in the current directory
- """
- if self.directory == dirname:
- self.in_project = True
-
-
- def cb_file_toggled(self, cellrenderertoggle, path, model):
- """!
- Event handler to handle the active state of the toggle buttons.
- @param cellrenderertoggle toggle that received the 'toggle' signal
- @param path cellrenderertoggle represented as a string
- @param model gtk.TreeStore model for the treeview
- """
- model[path][2] = not model[path][2]
-
-
- def get_schematics(self):
- """!
- Method to get to populate the gtk.TreeStore object self.schematics
- @return self.schematics (gtk.TreeStore object)
- """
- self.schematics = gtk.TreeStore(str, str, bool)
- # Get back a list of rows that have '.sch'
- lst = self.search(self.g.sources, self.match_func, (1, '.sch'))
- if lst != None:
- for f in lst:
- self.schematics.append(None, [f[1], f[2], True])
-
- return self.schematics
-
-
- def match_func(self, row, data):
- """!
- Method to see whether or not there is a matching schematic with the
- given row.
- @param row gtk.TreeModelRow object under observation
- @param data tuple used for the comparison criteria
- @return True if match, otherwise False
- """
- column, key = data
- return row[column].endswith(key)
-
-
- def search(self, rows, func, data, lst=None):
- """!
- Method to search for schematics in the project.
- @param rows gtk.TreeModel object or the object itself (due to recursion)
- @param func function pointer to the match_func method
- @param data tuple used for comparison criteria
- @param lst list used to store matching gtk.TreeModelRow objects
- @return list of gtk.TreeModelRow objects
- """
- if not rows:
- return None
- for row in rows:
- if func(row, data):
- if lst == None:
- lst = []
- lst.append(row)
- lst = self.search(row.iterchildren(), func, data, lst)
- if lst:
- return lst
- else:
- return None
-
diff --git a/src/gui/Gsch2pcb.py b/src/gui/Gsch2pcb.py
new file mode 100644
index 0000000..c8a8092
--- /dev/null
+++ b/src/gui/Gsch2pcb.py
@@ -0,0 +1,289 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.gui.Gsch2pcb
+#Gui for gsch2pcb workflow
+#@author Newell Jensen
+
+import os, gtk
+from subprocess import *
+
+
+class Gsch2pcb:
+ """
+ Message Dialog for the gsch2pcb workflow.
+ This class allows the user to select multiple schematics
+ to be used in the gsch2pcb workflow to produce a PCB file.
+ """
+ def __init__(self, mw, filepath):
+ """!
+ Gsch2pcb Constructor.
+ @param mwcurrent mw instance
+ @param filepath filepath of file to be automatically included
+ in the checklist of schematics
+ """
+ self.mw = mw
+ def response_to_dialog_directory(entry, dialog, response):
+ dialog.response(response)
+
+ def response_to_dialog_name(entry, dialog, response):
+ dialog.response(response)
+
+ def response_to_dialog_project(entry, dialog, response):
+ dialog.response(response)
+
+ def cb_directory_selection_changed(filechooser, directory_entry):
+ self.directory = self.filebutton.get_filename()
+ directory_entry.set_text(self.directory)
+
+ def cb_project_selection_changed(filechooser, project_entry):
+ self.projectpath = self.projectfile.get_filename()
+ self.project_entry.set_text(self.projectpath)
+
+
+ self.dialog = gtk.MessageDialog(self.mw,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_OTHER,
+ gtk.BUTTONS_OK_CANCEL,
+ gtk.STOCK_DIRECTORY)
+ self.dialog.set_markup('<b>Select one of the options below:</b>')
+ self.dialog.set_title('gsch2pcb workflow')
+
+ # Target Directory
+ hbox = gtk.HBox()
+ hbox.show()
+ directory_entry = gtk.Entry()
+ directory_entry.set_text(os.getcwd())
+ directory_entry.show()
+ directory_entry.connect('activate', response_to_dialog_directory, self.dialog, gtk.RESPONSE_OK)
+ self.filebutton = gtk.FileChooserButton('Target Directory')
+ self.filebutton.show()
+ self.filebutton.connect('selection-changed',
+ cb_directory_selection_changed, directory_entry)
+ self.filebutton.set_local_only(True)
+ self.filebutton.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
+ hbox.pack_end(self.filebutton)
+ hbox.pack_end(directory_entry)
+ label = gtk.Label('Target Directory:')
+ label.show()
+ hbox.pack_end(label)
+ self.dialog.vbox.pack_end(hbox, True, True, 0)
+
+ # PCB name
+ hbox = gtk.HBox()
+ hbox.show()
+ self.name_entry = gtk.Entry()
+ self.name_entry.show()
+ self.name_entry.connect('activate', response_to_dialog_name, self.dialog, gtk.RESPONSE_OK)
+ hbox.pack_end(self.name_entry)
+ label = gtk.Label('PCB Name (extension will be provided):')
+ label.show()
+ hbox.pack_end(label)
+ self.dialog.vbox.pack_end(hbox, True, True, 0)
+
+ # Schematic selections
+ scrolled_window = gtk.ScrolledWindow()
+ scrolled_window.show()
+ scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+ scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ # Get schematics in project no matter what directory
+ # They must be listed in the sources tree view though
+ self.schematics = self.get_schematics()
+ self.schematics_tree = gtk.TreeView(self.schematics)
+ self.schematics_tree.show()
+ column = gtk.TreeViewColumn('File', gtk.CellRendererText(), text=1)
+ self.schematics_tree.append_column(column)
+ toggle = gtk.CellRendererToggle()
+ toggle.set_property('activatable', True)
+ toggle.connect('toggled', self.cb_file_toggled, self.schematics)
+ column = gtk.TreeViewColumn('Include', toggle)
+ column.add_attribute(toggle, 'active', 2)
+ self.schematics_tree.append_column(column)
+ scrolled_window.add(self.schematics_tree)
+ self.dialog.vbox.pack_end(scrolled_window, True, True, 0)
+ self.dialog.show()
+
+ response = self.dialog.run()
+ if response == gtk.RESPONSE_OK:
+ message = ''
+ schematics_list = []
+ schematics = ''
+ self.in_project = False
+
+ # Iterate over the gtk.TreeModel to create an arg input for gsch2pcb
+ for row in self.schematics:
+ if row[2]:
+ # Add the schematic to the schematic_list
+ schematics_list.append(row[1])
+ schematics += row[1] + ' '
+ if not schematics_list:
+ message = 'At least one schematic must be chosen.\n'
+ name = self.name_entry.get_text()
+ if name == '' or name == None:
+ message += 'A name for the PCB must be specified.\n'
+ self.directory = directory_entry.get_text()
+ if self.directory == '' or self.directory == None:
+ message += 'A target directory must be chosen.\n'
+ else:
+ # Check to see if the target directory is in the project
+ # If so, set in_project flag to true
+ os.path.walk(self.directory, self.directory_match, None)
+
+ if message != '':
+ msg = message.rpartition('\n')[0]
+ dm = gtk.MessageDialog(self.mw.window,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_INFO,
+ gtk.BUTTONS_OK,
+ gtk.STOCK_DIRECTORY)
+ dm.set_markup(msg)
+ dm.show()
+ dm.run()
+ dm.destroy()
+ else:
+ os.chdir(self.directory)
+ files_before = os.listdir(self.directory)
+ subproc = Popen(['gsch2pcb', '-v','-v','-o',name,schematics], stdout=PIPE).wait()
+ ## print 'subproc:',subproc
+ ## print 'subproc.communicate()[0]:',subproc.communicate()[0]
+ ## self.mw.output_textbuffer.insert(self.mw.output_textiter, self.mw.utils.get_time() + ' and output from gsch2pcb:\n' + subproc.communicate()[0] + '.\n')
+
+ files_after = os.listdir(self.directory)
+ files = []
+ for f in files_after:
+ if f not in files_before:
+ files.append(f)
+
+ ## if self.in_project:
+ ## # Add it to the sources tree view
+ ## icon = gtk.IconTheme()
+ ## selection = self.mw.sources_tree.get_selection()
+ ## model, selection_iter = selection.get_selected()
+
+ ## if isinstance(selection_iter, gtk.TreeIter):
+ ## parent_iter = self.mw.sources.iter_parent(selection_iter)
+ ## else:
+ ## print model
+ ## print selection_iter
+ ## ## wanted = ['pcb','new.pcb','net']
+ ## ## new_files = []
+ ## ## new_files.append(True)
+ ## ## print 'files:',files
+ ## ## print 'parent_iter:',parent_iter
+ ## ## for f in files:
+ ## ## if f.endswith('new.pcb'):
+ ## ## ext = 'new.pcb'
+ ## ## else:
+ ## ## ext = f.split('.')[-1]
+ ## ## if ext in wanted:
+ ## ## filepath = self.directory + '/' + f
+ ## ## print 'filepath:',filepath
+ ## ## image = icon.load_icon(self.mw.utils.icon_lut[ext], 22, 0)
+ ## ## self.mw.sources.append(parent_iter, [image, f, filepath])
+ ## ## self.mw.dependencies.append(None, [f, filepath])
+ ## ## # add new file to the dependency_dict
+ ## ## if f not in self.mw.project.dependency_dict:
+ ## ## self.mw.project.dependency_dict[f] = [True]
+ ## ## new_files.append(f)
+ ## ## for sch in self.schematics:
+ ## ## if sch[0] not in self.mw.project.dependency_dict[sch[0]]:
+ ## ## self.mw.project.dependency_dict[sch[0]] = new_files
+ ## ## else:
+ ## ## self.mw.project.dependency_dict[sch[0]][0] = True
+ ## ## for f in new_files:
+ ## ## self.mw.project.dependency_dict[sch[0]].append(f)
+ ## ## # Update the project and its file list
+ ## ## self.mw.utils.update_file_list(self.mw)
+ ## else:
+ ## pass
+ self.dialog.destroy()
+
+
+ def directory_match(self, arg, dirname, filenames):
+ """!
+ Method to see whether or not the chosen directory for the gsch2pcb
+ workflow is in the project directory structure or not.
+ @param arg not used (needs to be here for the os.path.walk function)
+ @param dirname name of current directory
+ @param filenames list of file names in the current directory
+ """
+ if self.directory == dirname:
+ self.in_project = True
+
+
+ def cb_file_toggled(self, cellrenderertoggle, path, model):
+ """!
+ Event handler to handle the active state of the toggle buttons.
+ @param cellrenderertoggle toggle that received the 'toggle' signal
+ @param path cellrenderertoggle represented as a string
+ @param model gtk.TreeStore model for the treeview
+ """
+ model[path][2] = not model[path][2]
+
+
+ def get_schematics(self):
+ """!
+ Method to get to populate the gtk.TreeStore object self.schematics
+ @return self.schematics (gtk.TreeStore object)
+ """
+ self.schematics = gtk.TreeStore(str, str, bool)
+ # Get back a list of rows that have '.sch'
+ lst = self.search(self.mw.sources, self.match_func, (1, '.sch'))
+ if lst != None:
+ for f in lst:
+ self.schematics.append(None, [f[1], f[2], True])
+
+ return self.schematics
+
+
+ def match_func(self, row, data):
+ """!
+ Method to see whether or not there is a matching schematic with the
+ given row.
+ @param row gtk.TreeModelRow object under observation
+ @param data tuple used for the comparison criteria
+ @return True if match, otherwise False
+ """
+ column, key = data
+ return row[column].endswith(key)
+
+
+ def search(self, rows, func, data, lst=None):
+ """!
+ Method to search for schematics in the project.
+ @param rows gtk.TreeModel object or the object itself (due to recursion)
+ @param func function pointer to the match_func method
+ @param data tuple used for comparison criteria
+ @param lst list used to store matching gtk.TreeModelRow objects
+ @return list of gtk.TreeModelRow objects
+ """
+ if not rows:
+ return None
+ for row in rows:
+ if func(row, data):
+ if lst == None:
+ lst = []
+ lst.append(row)
+ lst = self.search(row.iterchildren(), func, data, lst)
+ if lst:
+ return lst
+ else:
+ return None
+
diff --git a/src/gui/Gsch2pcb.py.~1~ b/src/gui/Gsch2pcb.py.~1~
new file mode 100644
index 0000000..2b4f81b
--- /dev/null
+++ b/src/gui/Gsch2pcb.py.~1~
@@ -0,0 +1,291 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.gui.Gsch2pcb
+#Gui for gsch2pcb workflow
+#@author Newell Jensen
+
+import os, pygtk, gtk
+pygtk.require('2.0')
+from src.utils.Decorators import exceptions
+from subprocess import Popen, PIPE
+
+
+class Gsch2pcb:
+ """
+ Message Dialog for the gsch2pcb workflow.
+ This class allows the user to select multiple schematics
+ to be used in the gsch2pcb workflow to produce a PCB file.
+ """
+ def __init__(self, gedamanager, filepath):
+ """!
+ Gsch2pcb Constructor.
+ @param gedamanagercurrent gEDAManager instance
+ @param filepath filepath of file to be automatically included
+ in the checklist of schematics
+ """
+ self.g = gedamanager
+ def response_to_dialog_directory(entry, dialog, response):
+ dialog.response(response)
+
+ def response_to_dialog_name(entry, dialog, response):
+ dialog.response(response)
+
+ def response_to_dialog_project(entry, dialog, response):
+ dialog.response(response)
+
+ def cb_directory_selection_changed(filechooser, directory_entry):
+ self.directory = self.filebutton.get_filename()
+ directory_entry.set_text(self.directory)
+
+ def cb_project_selection_changed(filechooser, project_entry):
+ self.projectpath = self.projectfile.get_filename()
+ self.project_entry.set_text(self.projectpath)
+
+
+ self.dialog = gtk.MessageDialog(self.g.window,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_OTHER,
+ gtk.BUTTONS_OK_CANCEL,
+ gtk.STOCK_DIRECTORY)
+ self.dialog.set_markup('<b>Select one of the options below:</b>')
+ self.dialog.set_title('gsch2pcb workflow')
+
+ # Target Directory
+ hbox = gtk.HBox()
+ hbox.show()
+ directory_entry = gtk.Entry()
+ directory_entry.set_text(os.getcwd())
+ directory_entry.show()
+ directory_entry.connect('activate', response_to_dialog_directory, self.dialog, gtk.RESPONSE_OK)
+ self.filebutton = gtk.FileChooserButton('Target Directory')
+ self.filebutton.show()
+ self.filebutton.connect('selection-changed',
+ cb_directory_selection_changed, directory_entry)
+ self.filebutton.set_local_only(True)
+ self.filebutton.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
+ hbox.pack_end(self.filebutton)
+ hbox.pack_end(directory_entry)
+ label = gtk.Label('Target Directory:')
+ label.show()
+ hbox.pack_end(label)
+ self.dialog.vbox.pack_end(hbox, True, True, 0)
+
+ # PCB name
+ hbox = gtk.HBox()
+ hbox.show()
+ self.name_entry = gtk.Entry()
+ self.name_entry.show()
+ self.name_entry.connect('activate', response_to_dialog_name, self.dialog, gtk.RESPONSE_OK)
+ hbox.pack_end(self.name_entry)
+ label = gtk.Label('PCB Name (extension will be provided):')
+ label.show()
+ hbox.pack_end(label)
+ self.dialog.vbox.pack_end(hbox, True, True, 0)
+
+ # Schematic selections
+ scrolled_window = gtk.ScrolledWindow()
+ scrolled_window.show()
+ scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+ scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ # Get schematics in project no matter what directory
+ # They must be listed in the sources tree view though
+ self.schematics = self.get_schematics()
+ self.schematics_tree = gtk.TreeView(self.schematics)
+ self.schematics_tree.show()
+ column = gtk.TreeViewColumn('File', gtk.CellRendererText(), text=1)
+ self.schematics_tree.append_column(column)
+ toggle = gtk.CellRendererToggle()
+ toggle.set_property('activatable', True)
+ toggle.connect('toggled', self.cb_file_toggled, self.schematics)
+ column = gtk.TreeViewColumn('Include', toggle)
+ column.add_attribute(toggle, 'active', 2)
+ self.schematics_tree.append_column(column)
+ scrolled_window.add(self.schematics_tree)
+ self.dialog.vbox.pack_end(scrolled_window, True, True, 0)
+ self.dialog.show()
+
+ response = self.dialog.run()
+ if response == gtk.RESPONSE_OK:
+ message = ''
+ schematics_list = []
+ schematics = ''
+ self.in_project = False
+
+ # Iterate over the gtk.TreeModel to create an arg input for gsch2pcb
+ for row in self.schematics:
+ if row[2]:
+ # Add the schematic to the schematic_list
+ schematics_list.append(row[1])
+ schematics += row[1] + ' '
+ if not schematics_list:
+ message = 'At least one schematic must be chosen.\n'
+ name = self.name_entry.get_text()
+ if name == '' or name == None:
+ message += 'A name for the PCB must be specified.\n'
+ self.directory = directory_entry.get_text()
+ if self.directory == '' or self.directory == None:
+ message += 'A target directory must be chosen.\n'
+ else:
+ # Check to see if the target directory is in the project
+ # If so, set in_project flag to true
+ os.path.walk(self.directory, self.directory_match, None)
+
+ if message != '':
+ msg = message.rpartition('\n')[0]
+ dm = gtk.MessageDialog(self.g.window,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_INFO,
+ gtk.BUTTONS_OK,
+ gtk.STOCK_DIRECTORY)
+ dm.set_markup(msg)
+ dm.show()
+ dm.run()
+ dm.destroy()
+ else:
+ os.chdir(self.directory)
+ files_before = os.listdir(self.directory)
+ subproc = Popen(['gsch2pcb', '-v','-v','-o',name,schematics], stdout=PIPE).wait()
+ ## print 'subproc:',subproc
+ ## print 'subproc.communicate()[0]:',subproc.communicate()[0]
+ ## self.g.output_textbuffer.insert(self.g.output_textiter, self.g.utils.get_time() + ' and output from gsch2pcb:\n' + subproc.communicate()[0] + '.\n')
+
+ files_after = os.listdir(self.directory)
+ files = []
+ for f in files_after:
+ if f not in files_before:
+ files.append(f)
+
+ ## if self.in_project:
+ ## # Add it to the sources tree view
+ ## icon = gtk.IconTheme()
+ ## selection = self.g.sources_tree.get_selection()
+ ## model, selection_iter = selection.get_selected()
+
+ ## if isinstance(selection_iter, gtk.TreeIter):
+ ## parent_iter = self.g.sources.iter_parent(selection_iter)
+ ## else:
+ ## print model
+ ## print selection_iter
+ ## ## wanted = ['pcb','new.pcb','net']
+ ## ## new_files = []
+ ## ## new_files.append(True)
+ ## ## print 'files:',files
+ ## ## print 'parent_iter:',parent_iter
+ ## ## for f in files:
+ ## ## if f.endswith('new.pcb'):
+ ## ## ext = 'new.pcb'
+ ## ## else:
+ ## ## ext = f.split('.')[-1]
+ ## ## if ext in wanted:
+ ## ## filepath = self.directory + '/' + f
+ ## ## print 'filepath:',filepath
+ ## ## image = icon.load_icon(self.g.utils.icon_lut[ext], 22, 0)
+ ## ## self.g.sources.append(parent_iter, [image, f, filepath])
+ ## ## self.g.dependencies.append(None, [f, filepath])
+ ## ## # add new file to the dependency_dict
+ ## ## if f not in self.g.project.dependency_dict:
+ ## ## self.g.project.dependency_dict[f] = [True]
+ ## ## new_files.append(f)
+ ## ## for sch in self.schematics:
+ ## ## if sch[0] not in self.g.project.dependency_dict[sch[0]]:
+ ## ## self.g.project.dependency_dict[sch[0]] = new_files
+ ## ## else:
+ ## ## self.g.project.dependency_dict[sch[0]][0] = True
+ ## ## for f in new_files:
+ ## ## self.g.project.dependency_dict[sch[0]].append(f)
+ ## ## # Update the project and its file list
+ ## ## self.g.utils.update_file_list(self.g)
+ ## else:
+ ## pass
+ self.dialog.destroy()
+
+
+ def directory_match(self, arg, dirname, filenames):
+ """!
+ Method to see whether or not the chosen directory for the gsch2pcb
+ workflow is in the project directory structure or not.
+ @param arg not used (needs to be here for the os.path.walk function)
+ @param dirname name of current directory
+ @param filenames list of file names in the current directory
+ """
+ if self.directory == dirname:
+ self.in_project = True
+
+
+ def cb_file_toggled(self, cellrenderertoggle, path, model):
+ """!
+ Event handler to handle the active state of the toggle buttons.
+ @param cellrenderertoggle toggle that received the 'toggle' signal
+ @param path cellrenderertoggle represented as a string
+ @param model gtk.TreeStore model for the treeview
+ """
+ model[path][2] = not model[path][2]
+
+
+ def get_schematics(self):
+ """!
+ Method to get to populate the gtk.TreeStore object self.schematics
+ @return self.schematics (gtk.TreeStore object)
+ """
+ self.schematics = gtk.TreeStore(str, str, bool)
+ # Get back a list of rows that have '.sch'
+ lst = self.search(self.g.window.spd.sources, self.match_func, (1, '.sch'))
+ if lst != None:
+ for f in lst:
+ self.schematics.append(None, [f[1], f[2], True])
+
+ return self.schematics
+
+
+ def match_func(self, row, data):
+ """!
+ Method to see whether or not there is a matching schematic with the
+ given row.
+ @param row gtk.TreeModelRow object under observation
+ @param data tuple used for the comparison criteria
+ @return True if match, otherwise False
+ """
+ column, key = data
+ return row[column].endswith(key)
+
+
+ def search(self, rows, func, data, lst=None):
+ """!
+ Method to search for schematics in the project.
+ @param rows gtk.TreeModel object or the object itself (due to recursion)
+ @param func function pointer to the match_func method
+ @param data tuple used for comparison criteria
+ @param lst list used to store matching gtk.TreeModelRow objects
+ @return list of gtk.TreeModelRow objects
+ """
+ if not rows:
+ return None
+ for row in rows:
+ if func(row, data):
+ if lst == None:
+ lst = []
+ lst.append(row)
+ lst = self.search(row.iterchildren(), func, data, lst)
+ if lst:
+ return lst
+ else:
+ return None
+
diff --git a/src/gui/MainWindow.py b/src/gui/MainWindow.py
new file mode 100644
index 0000000..9c578b1
--- /dev/null
+++ b/src/gui/MainWindow.py
@@ -0,0 +1,380 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+import vte
+from src.utils.Callbacks import *
+from src.utils.Helpers import set_menu_defaults, set_sources_tree_to_project,\
+ set_dependencies_tree_to_project
+from src.utils.Decorators import exceptions
+from src.utils.Project import Project
+from src.utils.Settings import Settings
+from src.utils.DependencyLoop import DependencyLoop
+from src.utils.Icons import Icons
+
+class MainWindow(gtk.Window):
+ """
+ Top-level Window for the gEDA Manager.
+ This class takes care of all window logic
+ and communication with lower level objects.
+ """
+ def __init__(self):
+ gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
+ self.no_project_name = 'No project loaded...\n\n Select:\n Project->Open Project\n or Project->New Project'
+ self.icons = Icons()
+ self.settings = Settings()
+ if self.settings.project != None:
+ self.project = Project(self.settings.project)
+ else:
+ self.project = Project()
+
+ self.project.connect('closed', cb_project_closed, self)
+ self.project.connect('opened', cb_project_opened, self)
+ self.project.connect('created', cb_project_created, self)
+ self.dependencyloop = DependencyLoop(self)
+ self.connect('destroy', cb_destroy, self)
+ self.set_title('gEDA Manager')
+ self.set_icon_from_file('images/icons/geda-xgsch2pcb-48.png')
+ self.set_size_request(700,500)
+
+ # Create a Menu UIManager and a Popup UIManager
+ self.menu_uimanager = gtk.UIManager()
+ self.popup_uimanager = gtk.UIManager()
+ self.menu_accel_group = self.menu_uimanager.get_accel_group()
+ self.add_accel_group(self.menu_accel_group)
+ self.popup_accel_group = self.popup_uimanager.get_accel_group()
+ self.__init_tools__()
+ self.__init_menus__()
+ self.__init_gui_sections__()
+ self.__init_about_dialog__()
+ self.show()
+ set_menu_defaults(self)
+
+
+ #####################################################
+ # Initializer Methods -- methods to create the window
+ #####################################################
+
+ def __init_tools__(self):
+ """
+ Method to initialize attributes that will be used for the
+ subprocess instances of the gEDA tools.
+ """
+ # Check if .gmrc has an editor attribute
+ if self.settings.editor != None:
+ tools['editor'] = self.settings.editor
+
+
+ def __init_menus__(self):
+ """ Method to create the menu bar. """
+
+ actiongroup0 = gtk.ActionGroup('gEDAManager')
+ actiongroup0_list = [('Project', None, '_Project'),
+ ('New Project', None, 'Ne_w Project', None, 'Create New Project', cb_new_project),
+ ('Open Project', None, 'Open P_roject', None, 'Open Existing Project', cb_open_project),
+ ('Close Project', None, 'Close Projec_t', None, 'Close Active Project', cb_close_project),
+ ('Exit', gtk.STOCK_QUIT, 'E_xit', '<Control>q', 'Exit gEDA Manager', cb_exit),
+ ('Edit', None, '_Edit'),
+ ('Preferences...', gtk.STOCK_PREFERENCES, 'Pr_eferences', None,
+ 'gEDA Manager Preferences', cb_preferences),
+ ('Help', None, '_Help'),
+ ('gEDA Wiki', None, 'gEDA _Wiki', None, 'Opens link in browser',
+ cb_url_geda_wiki),
+ ('gEDA Documentation', None, 'gEDA _Documentation', None,
+ 'Opens link in browser', cb_url_geda_documentation),
+ ('gEDA Manager Documentation', None, 'gEDA _Manager Blog', None, 'Opens link in browser', cb_url_geda_manager_blog),
+ ('gEDA Manager API Documentation', None, 'gEDA Manager _API Documentation', None, 'Opens link in browser', cb_url_geda_manager_api_documentation),
+ ('Web Resources', None, '_Web Resources'),
+ ('About', gtk.STOCK_ABOUT, '_About', None, 'Extra Information about gEDA and the gEDA Manager', cb_show_about_dialog),]
+
+ actiongroup0.add_actions(actiongroup0_list, self)
+ self.menu_uimanager.insert_action_group(actiongroup0, 0)
+ merge_id = self.menu_uimanager.add_ui_from_file('src/gui/xml/menu.xml')
+ menubar = self.menu_uimanager.get_widget('/MenuBar')
+ self.vbox1 = gtk.VBox()
+ self.vbox1.show()
+ self.add(self.vbox1)
+ self.vbox1.pack_start(menubar, False, False, 0)
+
+ # Set up tooltips
+ tooltips = gtk.Tooltips()
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/New Project')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/New Project')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/Open Project')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/Open Project')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/Close Project')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/Exit')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/Exit')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Edit/Preferences...')
+ action = self.menu_uimanager.get_action('/MenuBar/Edit/Preferences...')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Manager Documentation')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Manager Documentation')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Documentation')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Documentation')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Wiki')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Wiki')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/About')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/About')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+
+
+ def __init_gui_sections__(self):
+ """ Method to create the main gui sections of the top-level window. """
+ # Partitioning the window
+ vpaned = gtk.VPaned()
+ vpaned.set_position(300)
+ self.vbox1.pack_start(vpaned, True, True, 0)
+ vpaned.show()
+
+ # Notebook
+ hpaned = gtk.HPaned() # This is the vpaned for sources and process
+ hpaned.set_position(350)
+ vpaned.pack1(hpaned, True, True)
+ hpaned.show()
+ sources_notebook = gtk.Notebook()
+ sources_notebook.show()
+ processes_notebook = gtk.Notebook()
+ processes_notebook.show()
+ sources_notebook.connect('switch-page', cb_switch_page, self)
+ processes_notebook.connect('switch-page', cb_switch_page, self)
+ hpaned.pack1(sources_notebook, True, True)
+ hpaned.pack2(processes_notebook, True, True)
+ sources_notebook.set_tab_pos(gtk.POS_BOTTOM)
+ processes_notebook.set_tab_pos(gtk.POS_BOTTOM)
+
+ scrolled_window_sources = gtk.ScrolledWindow()
+ scrolled_window_sources.show()
+ scrolled_window_processes = gtk.ScrolledWindow()
+ scrolled_window_processes.show()
+ scrolled_window_dependencies = gtk.ScrolledWindow()
+ scrolled_window_dependencies.show()
+ scrolled_window_sources.set_shadow_type(gtk.SHADOW_IN)
+ scrolled_window_sources.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scrolled_window_processes.set_shadow_type(gtk.SHADOW_IN)
+ scrolled_window_processes.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scrolled_window_dependencies.set_shadow_type(gtk.SHADOW_IN)
+ scrolled_window_dependencies.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+ sources_notebook.add(scrolled_window_sources)
+ processes_notebook.add(scrolled_window_processes)
+ sources_notebook.append_page(scrolled_window_dependencies)
+
+ # Labels
+ sources_label = gtk.Label('Sources')
+ sources_label.show()
+ dependencies_label = gtk.Label('Dependencies')
+ dependencies_label.show()
+ processes_label = gtk.Label('Processes')
+ processes_label.show()
+ sources_notebook.set_tab_label(sources_notebook.get_nth_page(0), sources_label)
+ sources_notebook.set_tab_label(sources_notebook.get_nth_page(1), dependencies_label)
+ processes_notebook.set_tab_label(processes_notebook.get_nth_page(0), processes_label)
+
+ # Models for the Tree Views
+ self.sources = gtk.TreeStore(gtk.gdk.Pixbuf, str, str)
+ self.processes = gtk.TreeStore(str, gtk.gdk.Pixbuf, gtk.gdk.Pixbuf)
+ self.dependencies = gtk.TreeStore(str, str)
+
+ # Source Tree View
+ self.sources_tree = gtk.TreeView(self.sources)
+ self.sources_tree.show()
+ self.sources_tree.connect('button_press_event', cb_button_press, self)
+ self.sources_tree.connect('row-activated', cb_sources_row_activated, self)
+ self.sources_tree.connect('cursor-changed', cb_cursor_changed, self)
+ column = gtk.TreeViewColumn(None, gtk.CellRendererPixbuf(), pixbuf=0)
+ self.sources_tree.append_column(column)
+ sources_cell = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(None, sources_cell, text=1)
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ self.sources_tree.append_column(column)
+
+ # Processes Tree View
+ self.processes_tree = gtk.TreeView(self.processes)
+ self.processes_tree.show()
+ self.processes_tree.connect('row-activated', cb_processes_row_activated, self)
+ column = gtk.TreeViewColumn('Processes for: ', gtk.CellRendererText(), text=0)
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ self.processes_tree.append_column(column)
+ processes_pixbuf = gtk.CellRendererPixbuf()
+ processes_pixbuf.set_property('xalign', 0.2)
+ column = gtk.TreeViewColumn(None, processes_pixbuf, pixbuf=1)
+ self.processes_tree.append_column(column)
+ column = gtk.TreeViewColumn(None, processes_pixbuf, pixbuf=2)
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ self.processes_tree.append_column(column)
+
+ # Dependencies Tree View
+ self.dependencies_tree = gtk.TreeView(self.dependencies)
+ self.dependencies_tree.show()
+ self.dependencies.connect('row-changed', cb_row_changed, self)
+
+ # create the TreeViewColumn to display the data
+ column = gtk.TreeViewColumn('Files')
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ dependencies_cell = gtk.CellRendererText()
+ column.pack_start(dependencies_cell, True)
+ column.add_attribute(dependencies_cell, 'text', 0)
+
+ # Allow sorting on the column
+ column.set_sort_column_id(0)
+ self.dependencies_tree.append_column(column)
+
+ # enable-tree-lines
+ self.sources_tree.set_property('enable-tree-lines', True)
+ self.processes_tree.set_property('enable-tree-lines', True)
+ self.dependencies_tree.set_property('enable-tree-lines', True)
+
+ # make it searchable
+ self.sources_tree.set_search_column(0)
+ self.processes_tree.set_search_column(0)
+ self.dependencies_tree.set_search_column(0)
+
+ # Allow drag and drop reordering of rows
+ self.dependencies_tree.set_reorderable(True)
+
+ # set tooltip columns
+ self.sources_tree.set_tooltip_column(2)
+ self.dependencies_tree.set_tooltip_column(1)
+
+ # add to the scrolling windows
+ scrolled_window_sources.add(self.sources_tree)
+ scrolled_window_processes.add(self.processes_tree)
+ scrolled_window_dependencies.add(self.dependencies_tree)
+
+ ######################################
+ # Lower Notebook Window
+ ######################################
+
+ notebook = gtk.Notebook()
+ notebook.show()
+ vpaned.pack2(notebook, True, True)
+ notebook.set_tab_pos(gtk.POS_BOTTOM)
+ terminal_scrolled_window = gtk.ScrolledWindow()
+ terminal_scrolled_window.show()
+
+ # Add a terminal to the terminal output notebook
+ current_directory = os.getcwd()
+ try:
+ os.chdir(self.project.directory)
+ except:
+ pass
+ self.terminal = vte.Terminal()
+ self.terminal.connect('child-exited', lambda term: cb_vte(self))
+ self.terminal.fork_command()
+ self.terminal.show()
+ os.chdir(current_directory)
+ terminal_scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+ terminal_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ terminal_scrolled_window.add_with_viewport(self.terminal)
+ notebook.add(terminal_scrolled_window)
+
+ icon = gtk.IconTheme()
+ terminal_icon = icon.load_icon(self.icons.icon_lut['terminal'], 22, 0)
+ terminal_pixbuf = gtk.Image()
+ terminal_pixbuf.set_from_pixbuf(terminal_icon)
+ notebook.set_tab_label(notebook.get_nth_page(0), terminal_pixbuf)
+
+ output_scolled_window = gtk.ScrolledWindow()
+ output_scolled_window.show()
+ output_scolled_window.set_shadow_type(gtk.SHADOW_IN)
+ output_scolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ notebook.add(output_scolled_window)
+
+ output_textview = gtk.TextView()
+ output_textview.set_editable(False)
+ output_textview.set_cursor_visible(False)
+ self.output_textbuffer = output_textview.get_buffer()
+ self.output_textiter = self.output_textbuffer.get_start_iter()
+ output_textview.show()
+ output_scolled_window.add(output_textview)
+
+ output_icon = icon.load_icon(self.icons.icon_lut['output'], 22, 0)
+ output_pixbuf = gtk.Image()
+ output_pixbuf.set_from_pixbuf(output_icon)
+ notebook.set_tab_label(notebook.get_nth_page(1), output_pixbuf)
+
+ errors_scrolled_window = gtk.ScrolledWindow()
+ errors_scrolled_window.show()
+ errors_scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+ errors_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ notebook.add(errors_scrolled_window)
+
+ errors_textview = gtk.TextView()
+ errors_textview.set_editable(False)
+ errors_textview.set_cursor_visible(False)
+ self.errors_textbuffer = errors_textview.get_buffer()
+ self.errors_textiter = self.errors_textbuffer.get_start_iter()
+ errors_textview.show()
+ errors_scrolled_window.add(errors_textview)
+
+ errors_icon = icon.load_icon(self.icons.icon_lut['errors'], 22, 0)
+ errors_pixbuf = gtk.Image()
+ errors_pixbuf.set_from_pixbuf(errors_icon)
+ notebook.set_tab_label(notebook.get_nth_page(2), errors_pixbuf)
+
+ self.output_textbuffer.insert(self.output_textiter, 'Output log--\n')
+ self.errors_textbuffer.insert(self.errors_textiter, 'Error log--\n')
+
+ # Finally add data to the sources_tree and the dependencies_tree
+ set_sources_tree_to_project(self)
+ set_dependencies_tree_to_project(self)
+
+ # Added for the time being until we get dependencies working
+ self.dependencies_tree.set_sensitive(False)
+
+
+ def __init_about_dialog__(self):
+ """ Method to create the about dialog. """
+
+ def about_url_cb(dialog, link, user_data):
+ """!
+ Call back function to test url for the about dialog
+ @param dialog about dialog object
+ @param link url link that was clicked
+ @param user_data user data that was passed in
+ """
+ gnomevfs.url_show(link)
+
+ self.aboutdialog = gtk.AboutDialog()
+ self.aboutdialog.set_name("gEDA Manager")
+ self.aboutdialog.set_license(__doc__)
+ self.aboutdialog.set_version(str(self.settings.version))
+ self.aboutdialog.set_copyright("gEDA Manager 2008")
+ self.aboutdialog.set_authors(['Newell Jensen', '--',
+ 'Before Enlightenment, chop wood and carry water',
+ 'After Enlightenment, code and build circuits'])
+ gtk.about_dialog_set_url_hook(about_url_cb, None)
+ self.aboutdialog.set_website('http://geda.seul.org')
+ self.aboutdialog.set_translator_credits('translator-credits')
+ self.aboutdialog.set_transient_for(self)
+
+
+
+
+
+
diff --git a/src/gui/MainWindow.py.~1~ b/src/gui/MainWindow.py.~1~
new file mode 100644
index 0000000..c106bde
--- /dev/null
+++ b/src/gui/MainWindow.py.~1~
@@ -0,0 +1,642 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+import gtk, pygtk, vte
+pygtk.require('2.0')
+from src.utils.Icons import Icons
+
+class MainWindow(gtk.Window):
+ """
+ Top-level Window for the gEDA Manager.
+ This class takes care of all window logic
+ and communication with lower level objects.
+ """
+ def __init__(self, gedamanager):
+ gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
+ self.gedamanager = gedamanager
+ self.icons = Icons()
+ self.connect('destroy', cb_destroy, self, self.gedamanager)
+ self.set_title('gEDA Manager')
+ # TODO create gEDA Manager icon
+ self.set_icon_from_file('images/icons/geda-xgsch2pcb-48.png')
+ self.set_size_request(700,500)
+ # Create a Menu UIManager and a Popup UIManager
+ self.menu_uimanager = gtk.UIManager()
+ self.popup_uimanager = gtk.UIManager()
+ self.menu_accel_group = self.menu_uimanager.get_accel_group()
+ self.add_accel_group(self.menu_accel_group)
+ self.popup_accel_group = self.popup_uimanager.get_accel_group()
+ self.__init_tools__()
+ self.__init_menus__()
+ self.__init_gui_sections__()
+ self.__init_about_dialog__()
+ self.set_menu_defaults()
+ self.show()
+
+
+ #####################################################
+ # Initializer Methods -- methods to create the window
+ #####################################################
+
+ def __init_tools__(self):
+ """
+ Method to initialize attributes that will be used for the
+ subprocess instances of the gEDA tools.
+ """
+ # Check if .gmrc has an editor attribute
+ if self.gedamanager.settings.editor != None:
+ tools['editor'] = self.gedamanager.settings.editor
+
+
+ def __init_menus__(self):
+ """ Method to create the menu bar. """
+
+ actiongroup0 = gtk.ActionGroup('gEDAManager')
+ actiongroup0_list = [('Project', None, '_Project'),
+ ('New Project', None, 'Ne_w Project', None, 'Create New Project', cb_new_project),
+ ('Open Project', None, 'Open P_roject', None, 'Open Existing Project', cb_open_project),
+ ('Close Project', None, 'Close Projec_t', None, 'Close Active Project', cb_close_project),
+ ('Exit', gtk.STOCK_QUIT, 'E_xit', '<Control>q', 'Exit gEDA Manager', cb_exit),
+ ('Edit', None, '_Edit'),
+ ('Preferences...', gtk.STOCK_PREFERENCES, 'Pr_eferences', None,
+ 'gEDA Manager Preferences', cb_preferences),
+ ('Help', None, '_Help'),
+ ('gEDA Wiki', None, 'gEDA _Wiki', None, 'Opens link in browser',
+ cb_url_geda_wiki),
+ ('gEDA Documentation', None, 'gEDA _Documentation', None,
+ 'Opens link in browser', cb_url_geda_documentation),
+ ('gEDA Manager Documentation', None, 'gEDA _Manager Blog', None, 'Opens link in browser', cb_url_geda_manager_blog),
+ ('gEDA Manager API Documentation', None, 'gEDA Manager _API Documentation', None, 'Opens link in browser', cb_url_geda_manager_api_documentation),
+ ('Web Resources', None, '_Web Resources'),
+ ('About', gtk.STOCK_ABOUT, '_About', None, 'Extra Information about gEDA and the gEDA Manager', cb_show_about_dialog),]
+
+ actiongroup0.add_actions(actiongroup0_list)
+ self.menu_uimanager.insert_action_group(actiongroup0, 0)
+ merge_id = self.menu_uimanager.add_ui_from_file('src/gui/xml/menu.xml')
+ menubar = self.menu_uimanager.get_widget('/MenuBar')
+ self.vbox1 = gtk.VBox()
+ self.vbox1.show()
+ self.add(self.vbox1)
+ self.vbox1.pack_start(menubar, False, False, 0)
+
+ # Set up tooltips
+ tooltips = gtk.Tooltips()
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/New Project')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/New Project')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/Open Project')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/Open Project')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/Close Project')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/Exit')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/Exit')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Edit/Preferences...')
+ action = self.menu_uimanager.get_action('/MenuBar/Edit/Preferences...')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Manager Documentation')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Manager Documentation')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Documentation')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Documentation')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Wiki')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Wiki')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/About')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/About')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+
+
+ def __init_gui_sections__(self):
+ """ Method to create the main gui sections of the top-level window. """
+ # Partitioning the window
+ vpaned = gtk.VPaned()
+ vpaned.set_position(300)
+ self.vbox1.pack_start(vpaned, True, True, 0)
+ vpaned.show()
+
+ # Notebook
+ hpaned = gtk.HPaned() # This is the vpaned for sources and process
+ hpaned.set_position(350)
+ vpaned.pack1(hpaned, True, True)
+ hpaned.show()
+ sources_notebook = gtk.Notebook()
+ sources_notebook.show()
+ processes_notebook = gtk.Notebook()
+ processes_notebook.show()
+ sources_notebook.connect('switch-page', cb_switch_page, self)
+ processes_notebook.connect('switch-page', cb_switch_page, self)
+ hpaned.pack1(sources_notebook, True, True)
+ hpaned.pack2(processes_notebook, True, True)
+ sources_notebook.set_tab_pos(gtk.POS_BOTTOM)
+ processes_notebook.set_tab_pos(gtk.POS_BOTTOM)
+
+ scrolled_window_sources = gtk.ScrolledWindow()
+ scrolled_window_sources.show()
+ scrolled_window_processes = gtk.ScrolledWindow()
+ scrolled_window_processes.show()
+ scrolled_window_dependencies = gtk.ScrolledWindow()
+ scrolled_window_dependencies.show()
+ scrolled_window_sources.set_shadow_type(gtk.SHADOW_IN)
+ scrolled_window_sources.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scrolled_window_processes.set_shadow_type(gtk.SHADOW_IN)
+ scrolled_window_processes.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scrolled_window_dependencies.set_shadow_type(gtk.SHADOW_IN)
+ scrolled_window_dependencies.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+ sources_notebook.add(scrolled_window_sources)
+ processes_notebook.add(scrolled_window_processes)
+ sources_notebook.append_page(scrolled_window_dependencies)
+
+ # Labels
+ sources_label = gtk.Label('Sources')
+ sources_label.show()
+ dependencies_label = gtk.Label('Dependencies')
+ dependencies_label.show()
+ processes_label = gtk.Label('Processes')
+ processes_label.show()
+ sources_notebook.set_tab_label(sources_notebook.get_nth_page(0), sources_label)
+ sources_notebook.set_tab_label(sources_notebook.get_nth_page(1), dependencies_label)
+ processes_notebook.set_tab_label(processes_notebook.get_nth_page(0), processes_label)
+
+ # Models for the Tree Views
+ self.sources = gtk.TreeStore(gtk.gdk.Pixbuf, str, str)
+ self.processes = gtk.TreeStore(str, gtk.gdk.Pixbuf, gtk.gdk.Pixbuf)
+ self.dependencies = gtk.TreeStore(str, str)
+
+ # Source Tree View
+ self.sources_tree = gtk.TreeView(self.sources)
+ self.sources_tree.show()
+ self.sources_tree.connect('button_press_event', cb_button_press, self, self.gedamanager)
+ self.sources_tree.connect('row-activated', cb_sources_row_activated, self, self.gedamanager)
+ self.sources_tree.connect('cursor-changed', cb_cursor_changed, self)
+ column = gtk.TreeViewColumn(None, gtk.CellRendererPixbuf(), pixbuf=0)
+ self.sources_tree.append_column(column)
+ sources_cell = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(None, sources_cell, text=1)
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ self.sources_tree.append_column(column)
+
+ # Processes Tree View
+ self.processes_tree = gtk.TreeView(self.processes)
+ self.processes_tree.show()
+ self.processes_tree.connect('row-activated', cb_processes_row_activated, self)
+ column = gtk.TreeViewColumn('Processes for: ', gtk.CellRendererText(), text=0)
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ self.processes_tree.append_column(column)
+ processes_pixbuf = gtk.CellRendererPixbuf()
+ processes_pixbuf.set_property('xalign', 0.2)
+ column = gtk.TreeViewColumn(None, processes_pixbuf, pixbuf=1)
+ self.processes_tree.append_column(column)
+ column = gtk.TreeViewColumn(None, processes_pixbuf, pixbuf=2)
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ self.processes_tree.append_column(column)
+
+ # Dependencies Tree View
+ self.dependencies_tree = gtk.TreeView(self.dependencies)
+ self.dependencies_tree.show()
+ self.dependencies.connect('row-changed', cb_row_changed, self.gedamanager)
+
+ # create the TreeViewColumn to display the data
+ column = gtk.TreeViewColumn('Files')
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ dependencies_cell = gtk.CellRendererText()
+ column.pack_start(dependencies_cell, True)
+ column.add_attribute(dependencies_cell, 'text', 0)
+
+ # Allow sorting on the column
+ column.set_sort_column_id(0)
+ self.dependencies_tree.append_column(column)
+
+ # enable-tree-lines
+ self.sources_tree.set_property('enable-tree-lines', True)
+ self.processes_tree.set_property('enable-tree-lines', True)
+ self.dependencies_tree.set_property('enable-tree-lines', True)
+
+ # make it searchable
+ self.sources_tree.set_search_column(0)
+ self.processes_tree.set_search_column(0)
+ self.dependencies_tree.set_search_column(0)
+
+ # Allow drag and drop reordering of rows
+ self.dependencies_tree.set_reorderable(True)
+
+ # set tooltip columns
+ self.sources_tree.set_tooltip_column(2)
+ self.dependencies_tree.set_tooltip_column(1)
+
+ # add to the scrolling windows
+ scrolled_window_sources.add(self.sources_tree)
+ scrolled_window_processes.add(self.processes_tree)
+ scrolled_window_dependencies.add(self.dependencies_tree)
+
+ ######################################
+ # Lower Notebook Window
+ ######################################
+
+ notebook = gtk.Notebook()
+ notebook.show()
+ vpaned.pack2(notebook, True, True)
+ notebook.set_tab_pos(gtk.POS_BOTTOM)
+ terminal_scrolled_window = gtk.ScrolledWindow()
+ terminal_scrolled_window.show()
+
+ # Add a terminal to the terminal output notebook
+ current_directory = os.getcwd()
+ try:
+ os.chdir(self.gedamanager.project.directory)
+ except:
+ pass
+ self.terminal = vte.Terminal()
+ self.terminal.connect('child-exited', lambda term: cb_vte())
+ self.terminal.fork_command()
+ self.terminal.show()
+ os.chdir(current_directory)
+ terminal_scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+ terminal_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ terminal_scrolled_window.add_with_viewport(self.terminal)
+ notebook.add(terminal_scrolled_window)
+
+ icon = gtk.IconTheme()
+ terminal_icon = icon.load_icon(self.icons.icon_lut['terminal'], 22, 0)
+ terminal_pixbuf = gtk.Image()
+ terminal_pixbuf.set_from_pixbuf(terminal_icon)
+ notebook.set_tab_label(notebook.get_nth_page(0), terminal_pixbuf)
+
+ output_scolled_window = gtk.ScrolledWindow()
+ output_scolled_window.show()
+ output_scolled_window.set_shadow_type(gtk.SHADOW_IN)
+ output_scolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ notebook.add(output_scolled_window)
+
+ output_textview = gtk.TextView()
+ output_textview.set_editable(False)
+ output_textview.set_cursor_visible(False)
+ self.output_textbuffer = output_textview.get_buffer()
+ self.output_textiter = self.output_textbuffer.get_start_iter()
+ output_textview.show()
+ output_scolled_window.add(output_textview)
+
+ output_icon = icon.load_icon(self.icons.icon_lut['output'], 22, 0)
+ output_pixbuf = gtk.Image()
+ output_pixbuf.set_from_pixbuf(output_icon)
+ notebook.set_tab_label(notebook.get_nth_page(1), output_pixbuf)
+
+ errors_scrolled_window = gtk.ScrolledWindow()
+ errors_scrolled_window.show()
+ errors_scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+ errors_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ notebook.add(errors_scrolled_window)
+
+ errors_textview = gtk.TextView()
+ errors_textview.set_editable(False)
+ errors_textview.set_cursor_visible(False)
+ self.errors_textbuffer = errors_textview.get_buffer()
+ self.errors_textiter = self.errors_textbuffer.get_start_iter()
+ errors_textview.show()
+ errors_scrolled_window.add(errors_textview)
+
+ errors_icon = icon.load_icon(self.icons.icon_lut['errors'], 22, 0)
+ errors_pixbuf = gtk.Image()
+ errors_pixbuf.set_from_pixbuf(errors_icon)
+ notebook.set_tab_label(notebook.get_nth_page(2), errors_pixbuf)
+
+ self.output_textbuffer.insert(self.output_textiter, 'Output log--\n')
+ self.errors_textbuffer.insert(self.errors_textiter, 'Error log--\n')
+
+ # Finally add data to the sources_tree and the dependencies_tree
+ self.set_sources_tree_to_project()
+ self.set_dependencies_tree_to_project()
+
+
+ def __init_about_dialog__(self):
+ """ Method to create the about dialog. """
+
+ def about_url_cb(dialog, link, user_data):
+ """!
+ Call back function to test url for the about dialog
+ @param dialog about dialog object
+ @param link url link that was clicked
+ @param user_data user data that was passed in
+ """
+ gnomevfs.url_show(link)
+
+ self.aboutdialog = gtk.AboutDialog()
+ self.aboutdialog.set_name("gEDA Manager")
+ self.aboutdialog.set_license(__doc__)
+ self.aboutdialog.set_version(str(self.gedamanager.settings.version))
+ self.aboutdialog.set_copyright("gEDA Manager 2008")
+ self.aboutdialog.set_authors(['Newell Jensen', '--',
+ 'Before Enlightenment, chop wood and carry water',
+ 'After Enlightenment, code and build circuits'])
+ gtk.about_dialog_set_url_hook(about_url_cb, None)
+ self.aboutdialog.set_website('http://geda.seul.org')
+ self.aboutdialog.set_translator_credits('translator-credits')
+ self.aboutdialog.set_transient_for(self)
+
+
+ ####################################
+ # Methods
+ ####################################
+
+ def set_menu_defaults(self):
+ """
+ Method to coordiante which methods should be called to handle
+ the sensitivity of the menu items.
+ """
+ # Project
+ if self.gedamanager.project.name == None or self.gedamanager.project.name == self.gedamanager.no_project_name:
+ self.set_no_project_default()
+ else:
+ self.set_project_default()
+
+
+ def set_no_project_default(self):
+ """
+ Method to set the default sensitivity when no project is loaded.
+ """
+ # File Menu
+ self.gedamanager.project.name = self.no_project_name
+ self.sources_tree.set_property('headers-visible', True)
+ column = self.sources_tree.get_column(0)
+ column.set_title(self.gedamanager.project.name)
+ save_project_as_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Save Project As...')
+ close_project_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+ close_project_menuitem.set_sensitive(False)
+
+
+ def set_project_default(self):
+ """
+ Method to set the default sensitivity when a project is loaded.
+ """
+ # File Menu
+ self.sources_tree.set_property('headers-visible', False)
+ save_project_as_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Save Project As...')
+ close_project_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+ close_project_menuitem.set_sensitive(True)
+
+
+ def set_project(self, path):
+ """!
+ Method to set current project to the one on path.
+ @param path path for project to open.
+ """
+ # Save current project
+ if not self.gedamanager.project.clean:
+ self.gedamanager.project.save()
+ self.gedamanager.project.open(path)
+ self.output_textbuffer.insert(self.output_textiter, get_time() + ':\n' + 'Project set to ' + self.gedamanager.project.name + '\n')
+ self.dependencyloop.switch_projects()
+
+
+ def set_sources_tree_to_project(self):
+ """ Method to set the tree to current project object. """
+ self.sources.clear()
+ if self.gedamanager.project.name != None:
+ self.load_sources_tree()
+ self.sources_tree.expand_all()
+
+
+ def set_dependencies_tree_to_project(self):
+ """ Method to set the tree to current project object. """
+ self.dependencies.clear()
+ if self.gedamanager.project.dependency_list != None:
+ self.load_dependencies_tree()
+ self.dependencies_tree.expand_all()
+
+
+ def set_dependencies_tree_to_new_project(self):
+ """ Method to set the tree to newly created project object. """
+ #self.dependencyloop.switch_projects()
+ self.dependencies.clear()
+ # Parent Folder
+ project_path = self.gedamanager.project.directory + '/' + self.gedamanager.project.name
+ project_file_path = project_path + '.gm'
+ output_file_path = self.gedamanager.project.directory + '/output.log'
+ error_file_path = self.gedamanager.project.directory + '/error.log'
+
+
+ def load_sources_tree(self):
+ """
+ Method to the load the 'Sources' TreeView from the
+ directory structure of the project.
+ """
+ if self.sources != None:
+ # Clear out the sources first
+ self.sources.clear()
+ # Start adding data to the Model
+ if isinstance(self.gedamanager.project.directory, str):
+ if os.path.exists(self.gedamanager.project.directory):
+ os.chdir(self.gedamanager.project.directory)
+ node = None
+ dictionary = {}
+ icon = gtk.IconTheme() # The icon used throughout the function
+ for root, dirs, files in os.walk(self.gedamanager.project.directory):
+ if root == self.gedamanager.project.directory:
+ image = icon.load_icon(self.icons.icon_lut['project'], 22, 0)
+ else:
+ image = icon.load_icon(self.icons.icon_lut['folder'], 22, 0)
+
+ folder = root.split('/')[-1]
+ try:
+ node = self.sources.append(dictionary[root], [image, folder, root])
+ except KeyError:
+ node = self.sources.append(None, [image, folder, root])
+ for f in [name for dec,name in sorted((os.path.splitext(f)[1][1:],f) for f in files)]: # List expression sorts by file extension
+ if not f.endswith(('~','-','#')):
+ image = icon.load_icon(self.icons.load_image(f), 22, 0)
+ self.sources.append(node, [image, f, os.path.join(root, f)])
+ for d in dirs:
+ dictionary[os.path.join(root, d)] = node
+
+ self.sources_tree.expand_all()
+
+
+ def load_dependencies_tree(self):
+ """!
+ Method to the load the dependencies tree
+ """
+ # Need to add checking for whether or not the filesystem still
+ # has the files before appending them to self.dependencies
+
+ # Either this or have a function that I call before this one that
+ # straightens it all out by going over the dependency_list and making
+ # sure that these files are the correct ones and if not it can call
+ # the functions remove/add/update_dependency() functions
+ def recurse_dependencies(dep_list, parent):
+ for value in dep_list:
+ filename = get_filename_from_filepath(value)
+ n_parent = self.dependenices.append(parent, [filename, value])
+ # recurse
+ if self.gedamanager.project.dependency_list[value] != []:
+ recurse_dependencies(self.gedamanager.project.dependency_list[value], n_parent)
+
+ if self.dependencies != None:
+ self.dependencies.clear()
+ for key, value in self.gedamanager.project.dependency_list.iteritems():
+ filename = get_filename_from_filepath(key)
+ n_parent = self.dependencies.append(None, [filename, key])
+ # recurse
+ if self.gedamanager.project.dependency_list[key] != []:
+ recurse_dependencies(value, n_parent)
+
+
+ def update_dependency(self, pathname, recurse=False):
+ # First, make sure that the file is already in the dependencies
+ if self.gedamanager.project.dependency_status != None:
+ try:
+ if not recurse:
+ self.gedamanager.project.dependency_status[pathname] = True
+ else:
+ self.gedamanager.project.dependency_status[pathname] = False
+ # recurse over the dependency_list
+ if self.gedamanager.project.dependency_list != None:
+ for value in self.gedamanager.project.dependency_list[pathname]:
+ self.update_dependency(value, True)
+ except KeyError:
+ print 'KeyError_update'
+ finally:
+ self.gedamanager.project.save()
+ self.load_dependencies_tree()
+
+
+ def add_dependency(self, pathname):
+ print 'in add_dependency'
+ try:
+ if self.gedamanager.project.dependency_list != None:
+ self.gedamanager.project.dependency_list[pathname] = []
+ if self.gedamanager.project.dependency_status != None:
+ self.gedamanager.project.dependency_status[pathname] = True
+ except KeyError:
+ print 'KeyError_add'
+ finally:
+ self.gedamanager.project.save()
+ self.load_dependencies_tree()
+
+
+ def remove_dependency(self, pathname, recurse=False):
+ # First, make sure that the file is already in the dependencies
+ if self.gedamanager.project.dependency_status != None:
+ if pathname in self.gedamanager.project.dependency_status:
+ try:
+ # iterate over the dependencies and flatten
+ for value in self.gedamanager.project.dependency_list[pathname]:
+ self.remove_dependency(value, True)
+ self.gedamanager.project.dependency_list[pathname] = []
+ except KeyError:
+ print 'KeyError_remove'
+ finally:
+ if not recurse:
+ del self.gedamanager.project.dependency_status[pathname]
+ del self.gedamanager.project.dependency_list[pathname]
+ else:
+ self.gedamanager.project.dependency_status[pathname] = False
+ self.gedamanager.project.save()
+ self.load_dependencies_tree()
+
+
+ ## def save_settings(self):
+ ## """ Method to save current settings to .gmrc file. """
+
+ ## if self.gedamanager.project.directory and self.gedamanager.project.name:
+ ## self.settings.project = self.gedamanager.project.directory + '/' + self.gedamanager.project.name + '.gm'
+ ## else:
+ ## self.settings.project = None
+ ## self.settings.create_config_file()
+
+
+ def get_processes_selected_node(self):
+ """!
+ Method to get the selected node in the 'Processes' treeview.
+ @return path of the selected node
+ """
+ selection = self.processes_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ return self.processes.get_value(selection_iter, 2)
+ else:
+ return None
+
+
+ def file_filters(self, dialog):
+ """!
+ Method to abstract some redundant code that is used in the message
+ dialog boxes.
+ @param dialog gtk.FileChooserDialog object
+ """
+ # These are subject to change depending on users input
+ # TODO -- see if we need these at all
+ # also see if we can add multiple filters per name e.g. .vhd and .vhdl
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("All files")
+ file_filter.add_pattern('*')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("schematics (.sch)")
+ file_filter.add_pattern('*.sch')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("symbols (.sym)")
+ file_filter.add_pattern('*.sym')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("pcb (.pcb)")
+ file_filter.add_pattern('*.pcb')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("verilog (.v)")
+ file_filter.add_pattern('*.v')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("vhdl (.vhd)")
+ file_filter.add_pattern('*.vhd')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("bom (.bom)")
+ file_filter.add_pattern('*.bom')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("drc (.drc)")
+ file_filter.add_pattern('*.drc')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("gerber (.gbr)")
+ file_filter.add_pattern('*.gbr')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("spice (.spice)")
+ file_filter.add_pattern('*.spice')
+ dialog.add_filter(file_filter)
+
+
+
+
diff --git a/src/gui/MainWindow.py.~2~ b/src/gui/MainWindow.py.~2~
new file mode 100644
index 0000000..4959e04
--- /dev/null
+++ b/src/gui/MainWindow.py.~2~
@@ -0,0 +1,2013 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+import gtk, pygtk, gobject
+pygtk.require('2.0')
+from src.utils.Decorators import exceptions
+from src.utils.Project import Project
+from src.utils.Settings import Settings
+from src.utils.DependencyLoop import DependencyLoop
+from src.gui.MainWindow import MainWindow
+from src.utils.Icons import Icons
+from src.utils.Callbacks import cb_project_closed, cb_project_opened, cb_project_created
+
+class MainWindow(gtk.Window):
+ """
+ Top-level Window for the gEDA Manager.
+ This class takes care of all window logic
+ and communication with lower level objects.
+ """
+ def __init__(self):
+ gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
+ self.no_project_name = 'No project loaded...\n\n Select:\n Project->Open Project\n or Project->New Project'
+ self.icons = Icons()
+ self.settings = Settings()
+ self.utils = Utils()
+ if self.settings.project != None:
+ self.project = Project(self.settings.project)
+ else:
+ self.project = Project()
+
+ self.project.connect('closed', self.cb_project_closed)
+ self.project.connect('saved', self.cb_project_saved)
+ self.project.connect('opened', self.cb_project_opened)
+ self.project.connect('created', self.cb_project_created)
+ self.dependencyloop = DependencyLoop(self)
+ self.connect('destroy', self.cb_destroy)
+ self.set_title('gEDA Manager')
+ self.set_icon_from_file('images/icons/geda-xgsch2pcb-48.png')
+ self.set_size_request(700,500)
+
+ # Create a Menu UIManager and a Popup UIManager
+ self.menu_uimanager = gtk.UIManager()
+ self.popup_uimanager = gtk.UIManager()
+ self.menu_accel_group = self.menu_uimanager.get_accel_group()
+ self.add_accel_group(self.menu_accel_group)
+ self.popup_accel_group = self.popup_uimanager.get_accel_group()
+ self.__init_tools__()
+ self.__init_menus__()
+ self.__init_gui_sections__()
+ self.__init_about_dialog__()
+ self.set_menu_defaults()
+ self.show()
+
+ #####################################################
+ # Initializer Methods -- methods to create the window
+ #####################################################
+
+ def __init_tools__(self):
+ """
+ Method to initialize attributes that will be used for the
+ subprocess instances of the gEDA tools.
+ """
+ # Check if .gmrc has an editor attribute
+ if self.gedamanager.settings.editor != None:
+ tools['editor'] = self.gedamanager.settings.editor
+
+
+ def __init_menus__(self):
+ """ Method to create the menu bar. """
+
+ actiongroup0 = gtk.ActionGroup('gEDAManager')
+ actiongroup0_list = [('Project', None, '_Project'),
+ ('New Project', None, 'Ne_w Project', None, 'Create New Project', cb_new_project),
+ ('Open Project', None, 'Open P_roject', None, 'Open Existing Project', cb_open_project),
+ ('Close Project', None, 'Close Projec_t', None, 'Close Active Project', cb_close_project),
+ ('Exit', gtk.STOCK_QUIT, 'E_xit', '<Control>q', 'Exit gEDA Manager', cb_exit),
+ ('Edit', None, '_Edit'),
+ ('Preferences...', gtk.STOCK_PREFERENCES, 'Pr_eferences', None,
+ 'gEDA Manager Preferences', cb_preferences),
+ ('Help', None, '_Help'),
+ ('gEDA Wiki', None, 'gEDA _Wiki', None, 'Opens link in browser',
+ cb_url_geda_wiki),
+ ('gEDA Documentation', None, 'gEDA _Documentation', None,
+ 'Opens link in browser', cb_url_geda_documentation),
+ ('gEDA Manager Documentation', None, 'gEDA _Manager Blog', None, 'Opens link in browser', cb_url_geda_manager_blog),
+ ('gEDA Manager API Documentation', None, 'gEDA Manager _API Documentation', None, 'Opens link in browser', cb_url_geda_manager_api_documentation),
+ ('Web Resources', None, '_Web Resources'),
+ ('About', gtk.STOCK_ABOUT, '_About', None, 'Extra Information about gEDA and the gEDA Manager', cb_show_about_dialog),]
+
+ actiongroup0.add_actions(actiongroup0_list)
+ self.menu_uimanager.insert_action_group(actiongroup0, 0)
+ merge_id = self.menu_uimanager.add_ui_from_file('src/gui/xml/menu.xml')
+ menubar = self.menu_uimanager.get_widget('/MenuBar')
+ self.vbox1 = gtk.VBox()
+ self.vbox1.show()
+ self.add(self.vbox1)
+ self.vbox1.pack_start(menubar, False, False, 0)
+
+ # Set up tooltips
+ tooltips = gtk.Tooltips()
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/New Project')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/New Project')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/Open Project')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/Open Project')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/Close Project')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/Exit')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/Exit')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Edit/Preferences...')
+ action = self.menu_uimanager.get_action('/MenuBar/Edit/Preferences...')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Manager Documentation')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Manager Documentation')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Documentation')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Documentation')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Wiki')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Wiki')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/About')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/About')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+
+
+ def __init_gui_sections__(self):
+ """ Method to create the main gui sections of the top-level window. """
+ # Partitioning the window
+ vpaned = gtk.VPaned()
+ vpaned.set_position(300)
+ self.vbox1.pack_start(vpaned, True, True, 0)
+ vpaned.show()
+
+ # Notebook
+ hpaned = gtk.HPaned() # This is the vpaned for sources and process
+ hpaned.set_position(350)
+ vpaned.pack1(hpaned, True, True)
+ hpaned.show()
+ sources_notebook = gtk.Notebook()
+ sources_notebook.show()
+ processes_notebook = gtk.Notebook()
+ processes_notebook.show()
+ sources_notebook.connect('switch-page', cb_switch_page, self)
+ processes_notebook.connect('switch-page', cb_switch_page, self)
+ hpaned.pack1(sources_notebook, True, True)
+ hpaned.pack2(processes_notebook, True, True)
+ sources_notebook.set_tab_pos(gtk.POS_BOTTOM)
+ processes_notebook.set_tab_pos(gtk.POS_BOTTOM)
+
+ scrolled_window_sources = gtk.ScrolledWindow()
+ scrolled_window_sources.show()
+ scrolled_window_processes = gtk.ScrolledWindow()
+ scrolled_window_processes.show()
+ scrolled_window_dependencies = gtk.ScrolledWindow()
+ scrolled_window_dependencies.show()
+ scrolled_window_sources.set_shadow_type(gtk.SHADOW_IN)
+ scrolled_window_sources.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scrolled_window_processes.set_shadow_type(gtk.SHADOW_IN)
+ scrolled_window_processes.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scrolled_window_dependencies.set_shadow_type(gtk.SHADOW_IN)
+ scrolled_window_dependencies.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+ sources_notebook.add(scrolled_window_sources)
+ processes_notebook.add(scrolled_window_processes)
+ sources_notebook.append_page(scrolled_window_dependencies)
+
+ # Labels
+ sources_label = gtk.Label('Sources')
+ sources_label.show()
+ dependencies_label = gtk.Label('Dependencies')
+ dependencies_label.show()
+ processes_label = gtk.Label('Processes')
+ processes_label.show()
+ sources_notebook.set_tab_label(sources_notebook.get_nth_page(0), sources_label)
+ sources_notebook.set_tab_label(sources_notebook.get_nth_page(1), dependencies_label)
+ processes_notebook.set_tab_label(processes_notebook.get_nth_page(0), processes_label)
+
+ # Models for the Tree Views
+ self.sources = gtk.TreeStore(gtk.gdk.Pixbuf, str, str)
+ self.processes = gtk.TreeStore(str, gtk.gdk.Pixbuf, gtk.gdk.Pixbuf)
+ self.dependencies = gtk.TreeStore(str, str)
+
+ # Source Tree View
+ self.sources_tree = gtk.TreeView(self.sources)
+ self.sources_tree.show()
+ self.sources_tree.connect('button_press_event', cb_button_press, self, self.gedamanager)
+ self.sources_tree.connect('row-activated', cb_sources_row_activated, self, self.gedamanager)
+ self.sources_tree.connect('cursor-changed', cb_cursor_changed, self)
+ column = gtk.TreeViewColumn(None, gtk.CellRendererPixbuf(), pixbuf=0)
+ self.sources_tree.append_column(column)
+ sources_cell = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(None, sources_cell, text=1)
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ self.sources_tree.append_column(column)
+
+ # Processes Tree View
+ self.processes_tree = gtk.TreeView(self.processes)
+ self.processes_tree.show()
+ self.processes_tree.connect('row-activated', cb_processes_row_activated, self)
+ column = gtk.TreeViewColumn('Processes for: ', gtk.CellRendererText(), text=0)
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ self.processes_tree.append_column(column)
+ processes_pixbuf = gtk.CellRendererPixbuf()
+ processes_pixbuf.set_property('xalign', 0.2)
+ column = gtk.TreeViewColumn(None, processes_pixbuf, pixbuf=1)
+ self.processes_tree.append_column(column)
+ column = gtk.TreeViewColumn(None, processes_pixbuf, pixbuf=2)
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ self.processes_tree.append_column(column)
+
+ # Dependencies Tree View
+ self.dependencies_tree = gtk.TreeView(self.dependencies)
+ self.dependencies_tree.show()
+ self.dependencies.connect('row-changed', cb_row_changed, self.gedamanager)
+
+ # create the TreeViewColumn to display the data
+ column = gtk.TreeViewColumn('Files')
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ dependencies_cell = gtk.CellRendererText()
+ column.pack_start(dependencies_cell, True)
+ column.add_attribute(dependencies_cell, 'text', 0)
+
+ # Allow sorting on the column
+ column.set_sort_column_id(0)
+ self.dependencies_tree.append_column(column)
+
+ # enable-tree-lines
+ self.sources_tree.set_property('enable-tree-lines', True)
+ self.processes_tree.set_property('enable-tree-lines', True)
+ self.dependencies_tree.set_property('enable-tree-lines', True)
+
+ # make it searchable
+ self.sources_tree.set_search_column(0)
+ self.processes_tree.set_search_column(0)
+ self.dependencies_tree.set_search_column(0)
+
+ # Allow drag and drop reordering of rows
+ self.dependencies_tree.set_reorderable(True)
+
+ # set tooltip columns
+ self.sources_tree.set_tooltip_column(2)
+ self.dependencies_tree.set_tooltip_column(1)
+
+ # add to the scrolling windows
+ scrolled_window_sources.add(self.sources_tree)
+ scrolled_window_processes.add(self.processes_tree)
+ scrolled_window_dependencies.add(self.dependencies_tree)
+
+ ######################################
+ # Lower Notebook Window
+ ######################################
+
+ notebook = gtk.Notebook()
+ notebook.show()
+ vpaned.pack2(notebook, True, True)
+ notebook.set_tab_pos(gtk.POS_BOTTOM)
+ terminal_scrolled_window = gtk.ScrolledWindow()
+ terminal_scrolled_window.show()
+
+ # Add a terminal to the terminal output notebook
+ current_directory = os.getcwd()
+ try:
+ os.chdir(self.gedamanager.project.directory)
+ except:
+ pass
+ self.terminal = vte.Terminal()
+ self.terminal.connect('child-exited', lambda term: cb_vte())
+ self.terminal.fork_command()
+ self.terminal.show()
+ os.chdir(current_directory)
+ terminal_scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+ terminal_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ terminal_scrolled_window.add_with_viewport(self.terminal)
+ notebook.add(terminal_scrolled_window)
+
+ icon = gtk.IconTheme()
+ terminal_icon = icon.load_icon(self.icons.icon_lut['terminal'], 22, 0)
+ terminal_pixbuf = gtk.Image()
+ terminal_pixbuf.set_from_pixbuf(terminal_icon)
+ notebook.set_tab_label(notebook.get_nth_page(0), terminal_pixbuf)
+
+ output_scolled_window = gtk.ScrolledWindow()
+ output_scolled_window.show()
+ output_scolled_window.set_shadow_type(gtk.SHADOW_IN)
+ output_scolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ notebook.add(output_scolled_window)
+
+ output_textview = gtk.TextView()
+ output_textview.set_editable(False)
+ output_textview.set_cursor_visible(False)
+ self.output_textbuffer = output_textview.get_buffer()
+ self.output_textiter = self.output_textbuffer.get_start_iter()
+ output_textview.show()
+ output_scolled_window.add(output_textview)
+
+ output_icon = icon.load_icon(self.icons.icon_lut['output'], 22, 0)
+ output_pixbuf = gtk.Image()
+ output_pixbuf.set_from_pixbuf(output_icon)
+ notebook.set_tab_label(notebook.get_nth_page(1), output_pixbuf)
+
+ errors_scrolled_window = gtk.ScrolledWindow()
+ errors_scrolled_window.show()
+ errors_scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+ errors_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ notebook.add(errors_scrolled_window)
+
+ errors_textview = gtk.TextView()
+ errors_textview.set_editable(False)
+ errors_textview.set_cursor_visible(False)
+ self.errors_textbuffer = errors_textview.get_buffer()
+ self.errors_textiter = self.errors_textbuffer.get_start_iter()
+ errors_textview.show()
+ errors_scrolled_window.add(errors_textview)
+
+ errors_icon = icon.load_icon(self.icons.icon_lut['errors'], 22, 0)
+ errors_pixbuf = gtk.Image()
+ errors_pixbuf.set_from_pixbuf(errors_icon)
+ notebook.set_tab_label(notebook.get_nth_page(2), errors_pixbuf)
+
+ self.output_textbuffer.insert(self.output_textiter, 'Output log--\n')
+ self.errors_textbuffer.insert(self.errors_textiter, 'Error log--\n')
+
+ # Finally add data to the sources_tree and the dependencies_tree
+ self.set_sources_tree_to_project()
+ self.set_dependencies_tree_to_project()
+
+
+ def __init_about_dialog__(self):
+ """ Method to create the about dialog. """
+
+ def about_url_cb(dialog, link, user_data):
+ """!
+ Call back function to test url for the about dialog
+ @param dialog about dialog object
+ @param link url link that was clicked
+ @param user_data user data that was passed in
+ """
+ gnomevfs.url_show(link)
+
+ self.aboutdialog = gtk.AboutDialog()
+ self.aboutdialog.set_name("gEDA Manager")
+ self.aboutdialog.set_license(__doc__)
+ self.aboutdialog.set_version(str(self.gedamanager.settings.version))
+ self.aboutdialog.set_copyright("gEDA Manager 2008")
+ self.aboutdialog.set_authors(['Newell Jensen', '--',
+ 'Before Enlightenment, chop wood and carry water',
+ 'After Enlightenment, code and build circuits'])
+ gtk.about_dialog_set_url_hook(about_url_cb, None)
+ self.aboutdialog.set_website('http://geda.seul.org')
+ self.aboutdialog.set_translator_credits('translator-credits')
+ self.aboutdialog.set_transient_for(self)
+
+
+ ## ####################################
+ ## # Methods
+ ## ####################################
+
+ ## def set_menu_defaults(self):
+ ## """
+ ## Method to coordiante which methods should be called to handle
+ ## the sensitivity of the menu items.
+ ## """
+ ## # Project
+ ## if self.gedamanager.project.name == None or self.gedamanager.project.name == self.gedamanager.no_project_name:
+ ## self.set_no_project_default()
+ ## else:
+ ## self.set_project_default()
+
+
+ ## def set_no_project_default(self):
+ ## """
+ ## Method to set the default sensitivity when no project is loaded.
+ ## """
+ ## # File Menu
+ ## self.gedamanager.project.name = self.no_project_name
+ ## self.sources_tree.set_property('headers-visible', True)
+ ## column = self.sources_tree.get_column(0)
+ ## column.set_title(self.gedamanager.project.name)
+ ## save_project_as_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Save Project As...')
+ ## close_project_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+ ## close_project_menuitem.set_sensitive(False)
+
+
+ ## def set_project_default(self):
+ ## """
+ ## Method to set the default sensitivity when a project is loaded.
+ ## """
+ ## # File Menu
+ ## self.sources_tree.set_property('headers-visible', False)
+ ## save_project_as_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Save Project As...')
+ ## close_project_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+ ## close_project_menuitem.set_sensitive(True)
+
+
+ ## def set_project(self, path):
+ ## """!
+ ## Method to set current project to the one on path.
+ ## @param path path for project to open.
+ ## """
+ ## # Save current project
+ ## if not self.gedamanager.project.clean:
+ ## self.gedamanager.project.save()
+ ## self.gedamanager.project.open(path)
+ ## self.output_textbuffer.insert(self.output_textiter, get_time() + ':\n' + 'Project set to ' + self.gedamanager.project.name + '\n')
+ ## self.dependencyloop.switch_projects()
+
+
+ ## def set_sources_tree_to_project(self):
+ ## """ Method to set the tree to current project object. """
+ ## self.sources.clear()
+ ## if self.gedamanager.project.name != None:
+ ## self.load_sources_tree()
+ ## self.sources_tree.expand_all()
+
+
+ ## def set_dependencies_tree_to_project(self):
+ ## """ Method to set the tree to current project object. """
+ ## self.dependencies.clear()
+ ## if self.gedamanager.project.dependency_list != None:
+ ## self.load_dependencies_tree()
+ ## self.dependencies_tree.expand_all()
+
+
+ ## def set_dependencies_tree_to_new_project(self):
+ ## """ Method to set the tree to newly created project object. """
+ ## #self.dependencyloop.switch_projects()
+ ## self.dependencies.clear()
+ ## # Parent Folder
+ ## project_path = self.gedamanager.project.directory + '/' + self.gedamanager.project.name
+ ## project_file_path = project_path + '.gm'
+ ## output_file_path = self.gedamanager.project.directory + '/output.log'
+ ## error_file_path = self.gedamanager.project.directory + '/error.log'
+
+
+ ## def load_sources_tree(self):
+ ## """
+ ## Method to the load the 'Sources' TreeView from the
+ ## directory structure of the project.
+ ## """
+ ## if self.sources != None:
+ ## # Clear out the sources first
+ ## self.sources.clear()
+ ## # Start adding data to the Model
+ ## if isinstance(self.gedamanager.project.directory, str):
+ ## if os.path.exists(self.gedamanager.project.directory):
+ ## os.chdir(self.gedamanager.project.directory)
+ ## node = None
+ ## dictionary = {}
+ ## icon = gtk.IconTheme() # The icon used throughout the function
+ ## for root, dirs, files in os.walk(self.gedamanager.project.directory):
+ ## if root == self.gedamanager.project.directory:
+ ## image = icon.load_icon(self.icons.icon_lut['project'], 22, 0)
+ ## else:
+ ## image = icon.load_icon(self.icons.icon_lut['folder'], 22, 0)
+
+ ## folder = root.split('/')[-1]
+ ## try:
+ ## node = self.sources.append(dictionary[root], [image, folder, root])
+ ## except KeyError:
+ ## node = self.sources.append(None, [image, folder, root])
+ ## for f in [name for dec,name in sorted((os.path.splitext(f)[1][1:],f) for f in files)]: # List expression sorts by file extension
+ ## if not f.endswith(('~','-','#')):
+ ## image = icon.load_icon(self.icons.load_image(f), 22, 0)
+ ## self.sources.append(node, [image, f, os.path.join(root, f)])
+ ## for d in dirs:
+ ## dictionary[os.path.join(root, d)] = node
+
+ ## self.sources_tree.expand_all()
+
+
+ ## def load_dependencies_tree(self):
+ ## """!
+ ## Method to the load the dependencies tree
+ ## """
+ ## # Need to add checking for whether or not the filesystem still
+ ## # has the files before appending them to self.dependencies
+
+ ## # Either this or have a function that I call before this one that
+ ## # straightens it all out by going over the dependency_list and making
+ ## # sure that these files are the correct ones and if not it can call
+ ## # the functions remove/add/update_dependency() functions
+ ## def recurse_dependencies(dep_list, parent):
+ ## for value in dep_list:
+ ## filename = get_filename_from_filepath(value)
+ ## n_parent = self.dependenices.append(parent, [filename, value])
+ ## # recurse
+ ## if self.gedamanager.project.dependency_list[value] != []:
+ ## recurse_dependencies(self.gedamanager.project.dependency_list[value], n_parent)
+
+ ## if self.dependencies != None:
+ ## self.dependencies.clear()
+ ## for key, value in self.gedamanager.project.dependency_list.iteritems():
+ ## filename = get_filename_from_filepath(key)
+ ## n_parent = self.dependencies.append(None, [filename, key])
+ ## # recurse
+ ## if self.gedamanager.project.dependency_list[key] != []:
+ ## recurse_dependencies(value, n_parent)
+
+
+ ## def update_dependency(self, pathname, recurse=False):
+ ## # First, make sure that the file is already in the dependencies
+ ## if self.gedamanager.project.dependency_status != None:
+ ## try:
+ ## if not recurse:
+ ## self.gedamanager.project.dependency_status[pathname] = True
+ ## else:
+ ## self.gedamanager.project.dependency_status[pathname] = False
+ ## # recurse over the dependency_list
+ ## if self.gedamanager.project.dependency_list != None:
+ ## for value in self.gedamanager.project.dependency_list[pathname]:
+ ## self.update_dependency(value, True)
+ ## except KeyError:
+ ## print 'KeyError_update'
+ ## finally:
+ ## self.gedamanager.project.save()
+ ## self.load_dependencies_tree()
+
+
+ ## def add_dependency(self, pathname):
+ ## print 'in add_dependency'
+ ## try:
+ ## if self.gedamanager.project.dependency_list != None:
+ ## self.gedamanager.project.dependency_list[pathname] = []
+ ## if self.gedamanager.project.dependency_status != None:
+ ## self.gedamanager.project.dependency_status[pathname] = True
+ ## except KeyError:
+ ## print 'KeyError_add'
+ ## finally:
+ ## self.gedamanager.project.save()
+ ## self.load_dependencies_tree()
+
+
+ ## def remove_dependency(self, pathname, recurse=False):
+ ## # First, make sure that the file is already in the dependencies
+ ## if self.gedamanager.project.dependency_status != None:
+ ## if pathname in self.gedamanager.project.dependency_status:
+ ## try:
+ ## # iterate over the dependencies and flatten
+ ## for value in self.gedamanager.project.dependency_list[pathname]:
+ ## self.remove_dependency(value, True)
+ ## self.gedamanager.project.dependency_list[pathname] = []
+ ## except KeyError:
+ ## print 'KeyError_remove'
+ ## finally:
+ ## if not recurse:
+ ## del self.gedamanager.project.dependency_status[pathname]
+ ## del self.gedamanager.project.dependency_list[pathname]
+ ## else:
+ ## self.gedamanager.project.dependency_status[pathname] = False
+ ## self.gedamanager.project.save()
+ ## self.load_dependencies_tree()
+
+
+ ## def get_processes_selected_node(self):
+ ## """!
+ ## Method to get the selected node in the 'Processes' treeview.
+ ## @return path of the selected node
+ ## """
+ ## selection = self.processes_tree.get_selection()
+ ## model, selection_iter = selection.get_selected()
+ ## if isinstance(selection_iter, gtk.TreeIter):
+ ## return self.processes.get_value(selection_iter, 2)
+ ## else:
+ ## return None
+
+
+ ## def file_filters(self, dialog):
+ ## """!
+ ## Method to abstract some redundant code that is used in the message
+ ## dialog boxes.
+ ## @param dialog gtk.FileChooserDialog object
+ ## """
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("All files")
+ ## file_filter.add_pattern('*')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("schematics (.sch)")
+ ## file_filter.add_pattern('*.sch')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("symbols (.sym)")
+ ## file_filter.add_pattern('*.sym')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("pcb (.pcb)")
+ ## file_filter.add_pattern('*.pcb')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("verilog (.v)")
+ ## file_filter.add_pattern('*.v')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("vhdl (.vhd)")
+ ## file_filter.add_pattern('*.vhd')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("bom (.bom)")
+ ## file_filter.add_pattern('*.bom')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("drc (.drc)")
+ ## file_filter.add_pattern('*.drc')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("gerber (.gbr)")
+ ## file_filter.add_pattern('*.gbr')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("spice (.spice)")
+ ## file_filter.add_pattern('*.spice')
+ ## dialog.add_filter(file_filter)
+
+
+#old
+## ###########################################################################
+## def __init_menus__(self):
+## """ Method to create the menu bar. """
+
+## actiongroup0 = gtk.ActionGroup('gEDAManager')
+## actiongroup0_list = [('Project', None, '_Project'),
+## ('New Project', None, 'Ne_w Project', None, 'Create New Project', self.cb_new_project),
+## ('Open Project', None, 'Open P_roject', None, 'Open Existing Project', self.cb_open_project),
+## ('Close Project', None, 'Close Projec_t', None, 'Close Active Project', self.cb_close_project),
+## ('Exit', gtk.STOCK_QUIT, 'E_xit', '<Control>q', 'Exit gEDA Manager', self.cb_exit),
+## ('Edit', None, '_Edit'),
+## ('Preferences...', gtk.STOCK_PREFERENCES, 'Pr_eferences', None,
+## 'gEDA Manager Preferences', self.cb_preferences),
+## ('Help', None, '_Help'),
+## ('gEDA Wiki', None, 'gEDA _Wiki', None, 'Opens link in browser',
+## self.cb_url_geda_wiki),
+## ('gEDA Documentation', None, 'gEDA _Documentation', None,
+## 'Opens link in browser', self.cb_url_geda_documentation),
+## ('gEDA Manager Documentation', None, 'gEDA _Manager Blog', None, 'Opens link in browser', self.cb_url_geda_manager_blog),
+## ('gEDA Manager API Documentation', None, 'gEDA Manager _API Documentation', None, 'Opens link in browser', self.cb_url_geda_manager_api_documentation),
+## ('Web Resources', None, '_Web Resources'),
+## ('About', gtk.STOCK_ABOUT, '_About', None, 'Extra Information about gEDA and the gEDA Manager', self.cb_show_about_dialog),]
+
+## actiongroup0.add_actions(actiongroup0_list)
+## self.menu_uimanager.insert_action_group(actiongroup0, 0)
+## merge_id = self.menu_uimanager.add_ui_from_file('menu.xml')
+## menubar = self.menu_uimanager.get_widget('/MenuBar')
+## self.vbox1 = gtk.VBox()
+## self.vbox1.show()
+## self.window.add(self.vbox1)
+## self.vbox1.pack_start(menubar, False, False, 0)
+
+## # Set up tooltips
+## tooltips = gtk.Tooltips()
+## widget = self.menu_uimanager.get_widget('/MenuBar/Project/New Project')
+## action = self.menu_uimanager.get_action('/MenuBar/Project/New Project')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Project/Open Project')
+## action = self.menu_uimanager.get_action('/MenuBar/Project/Open Project')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+## action = self.menu_uimanager.get_action('/MenuBar/Project/Close Project')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Project/Exit')
+## action = self.menu_uimanager.get_action('/MenuBar/Project/Exit')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Edit/Preferences...')
+## action = self.menu_uimanager.get_action('/MenuBar/Edit/Preferences...')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Manager Documentation')
+## action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Manager Documentation')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Documentation')
+## action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Documentation')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Wiki')
+## action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Wiki')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Help/About')
+## action = self.menu_uimanager.get_action('/MenuBar/Help/About')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+
+
+## def __init_gui_sections__(self):
+## """ Method to create the main gui sections of the top-level window. """
+## # Partitioning the window
+## hpaned = gtk.HPaned()
+## hpaned.set_position(400)
+## self.vbox1.pack_start(hpaned, True, True, 0)
+## hpaned.show()
+
+## # Notebook
+## vpaned = gtk.VPaned() # This is the vpaned for sources and process
+## hpaned.pack1(vpaned, True, True)
+## vpaned.show()
+## sources_notebook = gtk.Notebook()
+## sources_notebook.show()
+## processes_notebook = gtk.Notebook()
+## processes_notebook.show()
+## sources_notebook.connect('switch-page', self.cb_switch_page)
+## processes_notebook.connect('switch-page', self.cb_switch_page)
+## vpaned.pack1(sources_notebook, True, True)
+## vpaned.pack2(processes_notebook, True, True)
+## sources_notebook.set_tab_pos(gtk.POS_BOTTOM)
+## processes_notebook.set_tab_pos(gtk.POS_BOTTOM)
+
+## scrolled_window_sources = gtk.ScrolledWindow()
+## scrolled_window_sources.show()
+## scrolled_window_processes = gtk.ScrolledWindow()
+## scrolled_window_processes.show()
+## scrolled_window_dependencies = gtk.ScrolledWindow()
+## scrolled_window_dependencies.show()
+## scrolled_window_sources.set_shadow_type(gtk.SHADOW_IN)
+## scrolled_window_sources.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+## scrolled_window_processes.set_shadow_type(gtk.SHADOW_IN)
+## scrolled_window_processes.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+## scrolled_window_dependencies.set_shadow_type(gtk.SHADOW_IN)
+## scrolled_window_dependencies.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+## sources_notebook.add(scrolled_window_sources)
+## processes_notebook.add(scrolled_window_processes)
+## sources_notebook.append_page(scrolled_window_dependencies)
+
+## # Labels
+## sources_label = gtk.Label('Sources')
+## sources_label.show()
+## dependencies_label = gtk.Label('Dependencies')
+## dependencies_label.show()
+## processes_label = gtk.Label('Processes')
+## processes_label.show()
+## sources_notebook.set_tab_label(sources_notebook.get_nth_page(0), sources_label)
+## sources_notebook.set_tab_label(sources_notebook.get_nth_page(1), dependencies_label)
+## processes_notebook.set_tab_label(processes_notebook.get_nth_page(0), processes_label)
+
+## # Models for the Tree Views
+## self.sources = gtk.TreeStore(gtk.gdk.Pixbuf, str, str)
+## self.processes = gtk.TreeStore(str, gtk.gdk.Pixbuf, gtk.gdk.Pixbuf)
+## self.dependencies = gtk.TreeStore(str, str)
+
+## # Source Tree View
+## self.sources_tree = gtk.TreeView(self.sources)
+## self.sources_tree.show()
+## self.sources_tree.connect('button_press_event', self.cb_button_press)
+## self.sources_tree.connect('row-activated', self.utils.cb_sources_row_activated, self)
+## self.sources_tree.connect('cursor-changed', self.cb_cursor_changed)
+## column = gtk.TreeViewColumn(None, gtk.CellRendererPixbuf(), pixbuf=0)
+## self.sources_tree.append_column(column)
+## sources_cell = gtk.CellRendererText()
+## column = gtk.TreeViewColumn(None, sources_cell, text=1)
+## column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+## self.sources_tree.append_column(column)
+
+## # Processes Tree View
+## self.processes_tree = gtk.TreeView(self.processes)
+## self.processes_tree.show()
+## self.processes_tree.connect('row-activated', self.utils.cb_processes_row_activated, self)
+## column = gtk.TreeViewColumn('Processes for: ', gtk.CellRendererText(), text=0)
+## column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+## self.processes_tree.append_column(column)
+## processes_pixbuf = gtk.CellRendererPixbuf()
+## processes_pixbuf.set_property('xalign', 0.2)
+## column = gtk.TreeViewColumn(None, processes_pixbuf, pixbuf=1)
+## self.processes_tree.append_column(column)
+## column = gtk.TreeViewColumn(None, processes_pixbuf, pixbuf=2)
+## column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+## self.processes_tree.append_column(column)
+
+## # Dependencies Tree View
+## self.dependencies_tree = gtk.TreeView(self.dependencies)
+## self.dependencies_tree.show()
+## self.dependencies.connect('row-changed', self.cb_row_changed)
+
+## # create the TreeViewColumn to display the data
+## column = gtk.TreeViewColumn('Files')
+## column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+## dependencies_cell = gtk.CellRendererText()
+## column.pack_start(dependencies_cell, True)
+## column.add_attribute(dependencies_cell, 'text', 0)
+
+## # Allow sorting on the column
+## column.set_sort_column_id(0)
+## self.dependencies_tree.append_column(column)
+
+## # enable-tree-lines
+## self.sources_tree.set_property('enable-tree-lines', True)
+## self.processes_tree.set_property('enable-tree-lines', True)
+## self.dependencies_tree.set_property('enable-tree-lines', True)
+
+## # make it searchable
+## self.sources_tree.set_search_column(0)
+## self.processes_tree.set_search_column(0)
+## self.dependencies_tree.set_search_column(0)
+
+## # Allow drag and drop reordering of rows
+## self.dependencies_tree.set_reorderable(True)
+## self.sources_tree.set_reorderable(True)
+
+## # set tooltip columns
+## self.sources_tree.set_tooltip_column(2)
+## self.dependencies_tree.set_tooltip_column(1)
+
+## # add to the scrolling windows
+## scrolled_window_sources.add(self.sources_tree)
+## scrolled_window_processes.add(self.processes_tree)
+## scrolled_window_dependencies.add(self.dependencies_tree)
+
+## ######################################
+## # Lower Notebook Window
+## ######################################
+
+## notebook = gtk.Notebook()
+## notebook.show()
+## hpaned.pack2(notebook, True, True)
+## notebook.set_tab_pos(gtk.POS_BOTTOM)
+## terminal_scrolled_window = gtk.ScrolledWindow()
+## terminal_scrolled_window.show()
+
+## # Add a terminal to the terminal output notebook
+## current_directory = os.getcwd()
+## try:
+## os.chdir(self.project.directory)
+## except:
+## pass
+## self.terminal = vte.Terminal()
+## self.terminal.connect('child-exited', lambda term: self.cb_vte())#lambda term: gtk.main_quit())
+## self.terminal.fork_command()
+## self.terminal.show()
+## os.chdir(current_directory)
+## terminal_scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+## terminal_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+## terminal_scrolled_window.add_with_viewport(self.terminal)
+## notebook.add(terminal_scrolled_window)
+
+## icon = gtk.IconTheme()
+## terminal_icon = icon.load_icon(self.utils.icon_lut['terminal'], 22, 0)
+## terminal_pixbuf = gtk.Image()
+## terminal_pixbuf.set_from_pixbuf(terminal_icon)
+## notebook.set_tab_label(notebook.get_nth_page(0), terminal_pixbuf)
+
+## output_scolled_window = gtk.ScrolledWindow()
+## output_scolled_window.show()
+## output_scolled_window.set_shadow_type(gtk.SHADOW_IN)
+## output_scolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+## notebook.add(output_scolled_window)
+
+## output_textview = gtk.TextView()
+## output_textview.set_editable(False)
+## output_textview.set_cursor_visible(False)
+## self.output_textbuffer = output_textview.get_buffer()
+## self.output_textiter = self.output_textbuffer.get_start_iter()
+## output_textview.show()
+## output_scolled_window.add(output_textview)
+
+## output_icon = icon.load_icon(self.utils.icon_lut['output'], 22, 0)
+## output_pixbuf = gtk.Image()
+## output_pixbuf.set_from_pixbuf(output_icon)
+## notebook.set_tab_label(notebook.get_nth_page(1), output_pixbuf)
+
+## errors_scrolled_window = gtk.ScrolledWindow()
+## errors_scrolled_window.show()
+## errors_scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+## errors_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+## notebook.add(errors_scrolled_window)
+
+## errors_textview = gtk.TextView()
+## errors_textview.set_editable(False)
+## errors_textview.set_cursor_visible(False)
+## self.errors_textbuffer = errors_textview.get_buffer()
+## self.errors_textiter = self.errors_textbuffer.get_start_iter()
+## errors_textview.show()
+## errors_scrolled_window.add(errors_textview)
+
+## errors_icon = icon.load_icon(self.utils.icon_lut['errors'], 22, 0)
+## errors_pixbuf = gtk.Image()
+## errors_pixbuf.set_from_pixbuf(errors_icon)
+## notebook.set_tab_label(notebook.get_nth_page(2), errors_pixbuf)
+
+## self.output_textbuffer.insert(self.output_textiter, 'Output log--\n')
+## self.errors_textbuffer.insert(self.errors_textiter, 'Error log--\n')
+
+## # Finally add data to the sources_tree and the dependencies_tree
+## self.set_sources_tree_to_project()
+## self.set_dependencies_tree_to_project()
+
+
+## def __init_about_dialog__(self):
+## """ Method to create the about dialog. """
+
+## def about_url_cb(dialog, link, user_data):
+## """!
+## Call back function to test url for the about dialog
+## @param dialog about dialog object
+## @param link url link that was clicked
+## @param user_data user data that was passed in
+## """
+## gnomevfs.url_show(link)
+
+## self.aboutdialog = gtk.AboutDialog()
+## self.aboutdialog.set_name("gEDA Manager")
+## self.aboutdialog.set_license(__doc__)
+## self.aboutdialog.set_version(str(self.settings.version))
+## self.aboutdialog.set_copyright("gEDA Manager 2008")
+## self.aboutdialog.set_authors(['Newell Jensen', '--',
+## 'Before Enlightenment, chop wood and carry water',
+## 'After Enlightenment, code and build circuits'])
+## gtk.about_dialog_set_url_hook(about_url_cb, None)
+## self.aboutdialog.set_website('http://geda.seul.org')
+## self.aboutdialog.set_translator_credits('translator-credits')
+## self.aboutdialog.set_transient_for(self.window)
+
+
+## ####################################
+## # Methods
+## ####################################
+
+## def set_menu_defaults(self):
+## """
+## Method to coordiante which methods should be called to handle
+## the sensitivity of the menu items.
+## """
+## # Project
+## if self.project.name == None or self.project.name == self.no_project_name:
+## self.set_no_project_default()
+## else:
+## self.set_project_default()
+
+
+## def set_no_project_default(self):
+## """
+## Method to set the default sensitivity when no project is loaded.
+## """
+## # File Menu
+## self.project.name = self.no_project_name
+## self.sources_tree.set_property('headers-visible', True)
+## column = self.sources_tree.get_column(0)
+## column.set_title(self.project.name)
+## save_project_as_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Save Project As...')
+## close_project_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+## close_project_menuitem.set_sensitive(False)
+
+
+## def set_project_default(self):
+## """
+## Method to set the default sensitivity when a project is loaded.
+## """
+## # File Menu
+## self.sources_tree.set_property('headers-visible', False)
+## save_project_as_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Save Project As...')
+## close_project_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+## close_project_menuitem.set_sensitive(True)
+
+
+## def set_project(self, path):
+## """!
+## Method to set current project to the one on path.
+## @param path path for project to open.
+## """
+## # Save current project
+## if not self.project.clean:
+## self.project.save()
+## self.project.open(path)
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project set to ' + self.project.name + '\n')
+## self.dependencyloop.switch_projects()
+
+
+## def set_sources_tree_to_project(self):
+## """ Method to set the tree to current project object. """
+## self.sources.clear()
+## if self.project.name != None:
+## self.load_sources_tree()
+## self.sources_tree.expand_all()
+
+
+## def set_dependencies_tree_to_project(self):
+## """ Method to set the tree to current project object. """
+## self.dependencies.clear()
+## if self.project.dependency_list != None:
+## self.load_dependencies_tree()
+## self.dependencies_tree.expand_all()
+
+
+## def set_dependencies_tree_to_new_project(self):
+## """ Method to set the tree to newly created project object. """
+## #self.dependencyloop.switch_projects()
+## self.dependencies.clear()
+## # Parent Folder
+## project_path = self.project.directory + '/' + self.project.name
+## project_file_path = project_path + '.gm'
+## output_file_path = self.project.directory + '/output.log'
+## error_file_path = self.project.directory + '/error.log'
+
+
+## def load_sources_tree(self):
+## """
+## Method to the load the 'Sources' TreeView from the
+## directory structure of the project.
+## """
+## if self.sources != None:
+## # Clear out the sources first
+## self.sources.clear()
+## # Start adding data to the Model
+## if isinstance(self.project.directory, str):
+## if os.path.exists(self.project.directory):
+## os.chdir(self.project.directory)
+## node = None
+## dictionary = {}
+## icon = gtk.IconTheme() # The icon used throughout the function
+## for root, dirs, files in os.walk(self.project.directory):
+## if root == self.project.directory:
+## image = icon.load_icon(self.utils.icon_lut['project'], 22, 0)
+## else:
+## image = icon.load_icon(self.utils.icon_lut['folder'], 22, 0)
+
+## folder = root.split('/')[-1]
+## try:
+## node = self.sources.append(dictionary[root], [image, folder, root])
+## except KeyError:
+## node = self.sources.append(None, [image, folder, root])
+## for f in [name for dec,name in sorted((os.path.splitext(f)[1][1:],f) for f in files)]: # List expression sorts by file extension
+## if not f.endswith(('~','-','#')):
+## image = icon.load_icon(self.utils.load_image(f), 22, 0)
+## self.sources.append(node, [image, f, os.path.join(root, f)])
+## for d in dirs:
+## dictionary[os.path.join(root, d)] = node
+
+## self.sources_tree.expand_all()
+
+
+## def load_dependencies_tree(self):
+## """!
+## Method to the load the dependencies tree
+## """
+## # Need to add checking for whether or not the filesystem still
+## # has the files before appending them to self.dependencies
+
+## # Either this or have a function that I call before this one that
+## # straightens it all out by going over the dependency_list and making
+## # sure that these files are the correct ones and if not it can call
+## # the functions remove/add/update_dependency() functions
+## def recurse_dependencies(dep_list, parent):
+## for value in dep_list:
+## filename = self.utils.get_filename_from_filepath(value)
+## n_parent = self.dependenices.append(parent, [filename, value])
+## # recurse
+## if self.project.dependency_list[value] != []:
+## recurse_dependencies(self.project.dependency_list[value], n_parent)
+
+## if self.dependencies != None:
+## self.dependencies.clear()
+## for key, value in self.project.dependency_list.iteritems():
+## filename = self.utils.get_filename_from_filepath(key)
+## n_parent = self.dependencies.append(None, [filename, key])
+## # recurse
+## if self.project.dependency_list[key] != []:
+## recurse_dependencies(value, n_parent)
+
+
+## def update_dependency(self, pathname, recurse=False):
+## # First, make sure that the file is already in the dependencies
+## if self.project.dependency_status != None:
+## try:
+## if not recurse:
+## self.project.dependency_status[pathname] = True
+## else:
+## self.project.dependency_status[pathname] = False
+## # recurse over the dependency_list
+## if self.project.dependency_list != None:
+## for value in self.project.dependency_list[pathname]:
+## self.update_dependency(value, True)
+## except KeyError:
+## print 'KeyError_update'
+## finally:
+## self.project.save()
+## self.load_dependencies_tree()
+
+
+## def add_dependency(self, pathname):
+## print 'in add_dependency'
+## try:
+## if self.project.dependency_list != None:
+## self.project.dependency_list[pathname] = []
+## if self.project.dependency_status != None:
+## self.project.dependency_status[pathname] = True
+## except KeyError:
+## print 'KeyError_add'
+## finally:
+## self.project.save()
+## self.load_dependencies_tree()
+
+
+## def remove_dependency(self, pathname, recurse=False):
+## # First, make sure that the file is already in the dependencies
+## if self.project.dependency_status != None:
+## if pathname in self.project.dependency_status:
+## try:
+## # iterate over the dependencies and flatten
+## for value in self.project.dependency_list[pathname]:
+## self.remove_dependency(value, True)
+## self.project.dependency_list[pathname] = []
+## except KeyError:
+## print 'KeyError_remove'
+## finally:
+## if not recurse:
+## del self.project.dependency_status[pathname]
+## del self.project.dependency_list[pathname]
+## else:
+## self.project.dependency_status[pathname] = False
+## self.project.save()
+## self.load_dependencies_tree()
+
+
+## def save_settings(self):
+## """ Method to save current settings to .gmrc file. """
+
+## if self.project.directory and self.project.name:
+## self.settings.project = self.project.directory + '/' + self.project.name + '.gm'
+## else:
+## self.settings.project = None
+## self.settings.create_config_file()
+
+
+## def get_processes_selected_node(self):
+## """!
+## Method to get the selected node in the 'Processes' treeview.
+## @return path of the selected node
+## """
+## selection = self.processes_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## return self.processes.get_value(selection_iter, 2)
+## else:
+## return None
+
+
+## def file_filters(self, dialog):
+## """!
+## Method to abstract some redundant code that is used in the message
+## dialog boxes.
+## @param dialog gtk.FileChooserDialog object
+## """
+## # These are subject to change depending on users input
+## # TODO -- see if we need these at all
+## # also see if we can add multiple filters per name e.g. .vhd and .vhdl
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("All files")
+## file_filter.add_pattern('*')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("schematics (.sch)")
+## file_filter.add_pattern('*.sch')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("symbols (.sym)")
+## file_filter.add_pattern('*.sym')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("pcb (.pcb)")
+## file_filter.add_pattern('*.pcb')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("verilog (.v)")
+## file_filter.add_pattern('*.v')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("vhdl (.vhd)")
+## file_filter.add_pattern('*.vhd')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("bom (.bom)")
+## file_filter.add_pattern('*.bom')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("drc (.drc)")
+## file_filter.add_pattern('*.drc')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("gerber (.gbr)")
+## file_filter.add_pattern('*.gbr')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("spice (.spice)")
+## file_filter.add_pattern('*.spice')
+## dialog.add_filter(file_filter)
+
+
+## @exceptions
+## def write_logs(self):
+## """
+## Method to write out the error and output logs with what is in
+## the textbuffers.
+## """
+## startiter, enditer = self.output_textbuffer.get_bounds()
+## output = self.output_textbuffer.get_text(startiter, enditer)
+## os.chdir(self.project.directory)
+## f = file('output.log', 'a')
+## f.writelines(output)
+## f.close()
+
+## startiter, enditer = self.errors_textbuffer.get_bounds()
+## errors = self.errors_textbuffer.get_text(startiter, enditer)
+## os.chdir(self.project.directory)
+## f = file('error.log', 'a')
+## f.writelines(errors)
+## f.close()
+
+
+## @exceptions
+## def kill_processes(self):
+## """
+## Method to kill all the open processes if there are still any
+## open when the gEDAManager is closed.
+## """
+## # TODO - if open processes's prompt the user to save work
+## # before exiting
+## # e.g.
+## # "You have open processes. If you exit you may lose unsaved
+## # changes. Would you like to proceed? Okay or Cancel.
+## for tool, value in self.tools.iteritems():
+## if value != None and not isinstance(value, str): # kill the process
+## os.kill(value.pid, signal.SIGKILL)
+
+
+## ######################################################
+## # Callback Methods -- signal handlers are event driven
+## ######################################################
+
+## def cb_show_about_dialog(self, menuitem, data=None):
+## """!
+## Event handler for About menu button.
+## @param menuitem about menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## self.aboutdialog.show()
+## self.aboutdialog.run()
+## self.aboutdialog.hide()
+
+
+## def cb_url_geda_wiki(self, menuitem, data=None):
+## """!
+## Event handler for gEDA Wiki.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## gnomevfs.url_show('http://geda.seul.org/wiki/')
+
+
+## def cb_url_geda_documentation(self, menuitem, data=None):
+## """!
+## Event handler for gEDA Documentation.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## gnomevfs.url_show('http://geda.seul.org/wiki/geda:documentation')
+
+
+## def cb_url_geda_manager_blog(self, menuitem, data=None):
+## """!
+## Event handler for gEDA Manager.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## gnomevfs.url_show('http://www.gempillar.com')
+
+
+## def cb_url_geda_manager_api_documentation(self, menuitem, data=None):
+## """!
+## Event handler for gEDA Manager.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## gnomevfs.url_show('http://www.gempillar.com/docs/geda-manager')
+
+
+## def cb_new_project(self, menuitem, data=None):
+## """!
+## Event handler for 'New Project'.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## self.project.save()
+## NewProject(self)
+
+
+## def cb_open_project(self, menuitem, data=None):
+## """!
+## Event handler for 'Open Project'.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## self.project.save()
+## dialog = gtk.FileChooserDialog('Open...',
+## self.window,
+## gtk.FILE_CHOOSER_ACTION_OPEN,
+## (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+## gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+
+## dialog.set_default_response(gtk.RESPONSE_OK)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("Project files (*.gm)")
+## file_filter.add_pattern('*.gm')
+## dialog.add_filter(file_filter)
+
+## response = dialog.run()
+## if response == gtk.RESPONSE_OK:
+## self.set_project(dialog.get_filename())
+## dialog.destroy()
+
+
+## def cb_close_project(self, menuitem, data=None):
+## """!
+## Event handler for 'Close Project'.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## self.write_logs()
+## self.project.save()
+## self.project.close()
+## # clear the processes window
+## self.processes.clear()
+
+
+## def cb_project_closed(self, widget, event):
+## """!
+## Event occurs when a Project object is closed
+## @param widget widget that threw the event
+## @param event event that was thrown
+## """
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project closed.\n')
+## self.set_menu_defaults()
+## self.set_sources_tree_to_project()
+## self.set_dependencies_tree_to_project()
+
+
+## def cb_project_saved(self, widget, event):
+## """!
+## Event occurs when a Project object is saved.
+## @param widget widget that threw the event
+## @param event event that was thrown
+## """
+## if self.project.name != None:
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project ' + self.project.name + ' saved.\n')
+## else:
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project saved.\n')
+## self.set_menu_defaults()
+
+
+## def cb_project_opened(self, widget, event):
+## """!
+## Event occurs when a Project object is opened
+## @param widget widget that threw the event
+## @param event event that was thrown
+## """
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project ' + self.project.name + ' opened.\n')
+## self.set_menu_defaults()
+## self.set_sources_tree_to_project()
+## self.set_dependencies_tree_to_project()
+
+
+## def cb_project_created(self, widget, event):
+## """!
+## Event occurs when a Project object is created
+## @param widget widget that threw the event
+## @param event event that was thrown
+## """
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nProject ' + self.project.name + ' created.\n')
+## self.set_menu_defaults()
+## self.set_sources_tree_to_project()
+## self.set_dependencies_tree_to_new_project()
+
+
+## @exceptions
+## def cb_preferences(self, menuitem, data=None):
+## """!
+## Event occurs when the user opens up the preferences menu.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## def new_source_cursor_changed(newsources_tree):
+## selection = newsources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## self.newsource = model.get_value(selection_iter, 1)
+
+## if self.settings.editor != None:
+## old_editor = self.settings.editor
+## else:
+## old_editor = None
+
+## def response_to_dialog(entry, dialog, response):
+## dialog.response(response)
+
+## entry = gtk.Entry()
+## if self.settings.editor != None:
+## entry.set_text(self.settings.editor)
+## entry.show()
+
+## def cb_filebutton_selection_changed(filechooser, entry):
+## self.settings.editor = filebutton.get_filename()
+## entry.delete_text(0,-1)
+## entry.set_text(self.settings.editor)
+
+## dialog = gtk.MessageDialog(self.window,
+## (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+## gtk.MESSAGE_OTHER,
+## gtk.BUTTONS_OK_CANCEL,
+## gtk.STOCK_DIRECTORY)
+## dialog.set_markup('<b>Preference settings:</b>')
+## dialog.set_title('Preferences')
+## hbox = gtk.HBox()
+## hbox.show()
+
+## filebutton = gtk.FileChooserButton('Text Editor')
+## filebutton.show()
+## filebutton.connect('selection-changed',
+## cb_filebutton_selection_changed, entry)
+## filebutton.set_local_only(True)
+## filebutton.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
+## hbox.pack_end(filebutton)
+
+## entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+## hbox.pack_end(entry)
+## label = gtk.Label('Text Editor:')
+## label.show()
+## hbox.pack_end(label)
+
+## dialog.vbox.pack_end(hbox, True, True, 0)
+## dialog.show()
+## dialog.run()
+## if old_editor != self.settings.editor: # A change was made
+## new_text = self.settings.editor
+## else:
+## new_text = entry.get_text()
+## dialog.destroy()
+
+## if new_text:
+## self.settings.editor = new_text
+
+
+## @exceptions
+## def cb_new_source(self, menuitem, data=None):
+## """!
+## Event occurs when the user wants to add a source to the project
+## @param menuitem menutiem that threw the event
+## @param data optional user data to pass in
+## """
+## def new_source_cursor_changed(newsources_tree):
+## selection = newsources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## self.newsource = model.get_value(selection_iter, 1)
+## else:
+## self.newsource = None
+
+## def response_to_dialog(entry, dialog, response):
+## dialog.response(response)
+
+
+## dialog = gtk.MessageDialog(self.window,
+## (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+## gtk.MESSAGE_QUESTION,
+## gtk.BUTTONS_OK_CANCEL,
+## gtk.STOCK_DIRECTORY)
+## dialog.set_markup('<b>Please enter the new file name (extension will be added):</b>')#\n(add extension to override defaults):</b>')
+## entry = gtk.Entry()
+## entry.show()
+## entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+## hbox = gtk.HBox()
+## hbox.show()
+## hbox.pack_end(entry)
+## label = gtk.Label('File name:')
+## label.show()
+## hbox.pack_end(label)
+
+## # Models for the Tree View
+## newsources = gtk.TreeStore(gtk.gdk.Pixbuf, str)
+## # Tree View
+## newsources_tree = gtk.TreeView(newsources)
+## newsources_tree.show()
+## newsources_tree.connect('cursor-changed', new_source_cursor_changed)
+## # column headings
+## newsources_pixbuf = gtk.CellRendererPixbuf()
+## newsources_pixbuf.set_property('xalign', 0)
+## column = gtk.TreeViewColumn(None, newsources_pixbuf, pixbuf=0)
+## newsources_tree.append_column(column)
+## newsources_cell = gtk.CellRendererText()
+## column = gtk.TreeViewColumn('Source Type', newsources_cell, text=1)
+## column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+## newsources_tree.append_column(column)
+## # populate the tree view
+## icon = gtk.IconTheme()
+## image = icon.load_icon(self.utils.icon_lut['pcb'], 22, 0)
+## newsources.append(None, [image, 'PCB (.pcb)'])
+## image = icon.load_icon(self.utils.icon_lut['sch'], 22, 0)
+## newsources.append(None, [image, 'Schematic (.sch)'])
+## image = icon.load_icon(self.utils.icon_lut['v'], 22, 0)
+## newsources.append(None, [image, 'Verilog (.v)'])
+## image = icon.load_icon(self.utils.icon_lut['vhd'], 22, 0)
+## newsources.append(None, [image, 'VHDL (.vhd)'])
+## image = icon.load_icon(self.utils.icon_lut['sym'], 22, 0)
+## newsources.append(None, [image, 'Symbol (.sym)'])
+
+## # add to the hbox
+## hbox.pack_start(newsources_tree, False, False)
+## dialog.vbox.pack_end(hbox, True, True, 0)
+
+## dialog.show()
+## dialog.run()
+## new_text = entry.get_text()
+## dialog.destroy()
+
+## if new_text and self.newsource != None:
+## # Get the selected_node for the folder to add to
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## selected_node = self.sources.get_value(selection_iter, 2)
+## # Get the type of extension for the program to call
+## if '.' in new_text: # user may have overriden extension
+## return
+## else: # Need to find out what extension from the highlighted node
+## ext = self.newsource[self.newsource.find('.')+1:self.newsource.find(')')]
+## # Make sure a file with the same name doesn't already exist
+## filepath = selected_node + '/' + new_text + '.' + ext
+## filename = new_text + '.' + ext
+## self.utils.update_file_list(self, 1, filepath)
+## self.utils.run_command(self, filepath, None, ext)
+## else:
+## dialog = gtk.MessageDialog(self.window,
+## (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+## gtk.MESSAGE_INFO,
+## gtk.BUTTONS_OK,
+## gtk.STOCK_DIRECTORY)
+## dialog.set_markup('<b>Please enter text and/or make sure a file type is selected.</b>')
+## dialog.show()
+## response = dialog.run()
+## dialog.destroy()
+
+
+## @exceptions
+## def cb_add_copy_source(self, menuitem, data=None):
+## """!
+## Event occurs when the user wants to add a source to the project
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## dialog = gtk.FileChooserDialog('Copy Existing Source To Project...',
+## self.window,
+## gtk.FILE_CHOOSER_ACTION_OPEN,
+## (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+## gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+
+## dialog.set_default_response(gtk.RESPONSE_OK)
+## self.file_filters(dialog)
+## response = dialog.run()
+## if response == gtk.RESPONSE_OK:
+## filepath = dialog.get_filename()
+## self.utils.update_file_list(self, 0, filepath)
+## dialog.destroy()
+
+
+## @exceptions
+## def cb_new_folder(self, action):
+## """!
+## Event occurs when the user chooses to add a new folder to the project.
+## @param action gtk.Action object
+## """
+## def response_to_dialog(entry, dialog, response):
+## dialog.response(response)
+
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## selected_node = self.sources.get_value(selection_iter, 2)
+## if '.' in selected_node:
+## # This is not a folder
+## # YES, this is a hack and was put in place because
+## # we get some problems if the use right clicks on a node before
+## # it becomes highlighted.
+## return
+## os.chdir(selected_node)
+## dialog = gtk.MessageDialog(self.window,
+## (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+## gtk.MESSAGE_QUESTION,
+## gtk.BUTTONS_OK_CANCEL,
+## gtk.STOCK_DIRECTORY)
+## dialog.set_markup('<b>Please enter new folder name:</b>\nIf the folder name you choose exists\non disk in this directory it will deleted.')
+## entry = gtk.Entry()
+## entry.show()
+## entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+## hbox = gtk.HBox()
+## hbox.show()
+## hbox.pack_end(entry)
+## dialog.vbox.pack_end(hbox, True, True, 0)
+## dialog.show()
+## response = dialog.run()
+## text = entry.get_text()
+## if response == gtk.RESPONSE_OK and text.strip() != '':
+## filepath = selected_node + '/' + text
+
+## def delete_dependency_list_entry(arg, dirname, filenames):
+## """ function to delete the filenames from the dependency_list """
+## for f in filenames:
+## print 'looking to delete dependency'
+## if f in self.project.dependency_list and list(self.utils.flatten(self.project.file_list)).count(f) == 1:
+## print 'deleting dependency'
+## del self.project.dependency_list[f]
+
+## # See if this directory already exists
+## if os.path.exists(filepath): # delete directory recursively
+## os.path.walk(filepath, delete_dependency_list_entry, None)
+## shutil.rmtree(filepath)
+## flag = True
+## i = 0
+## while flag:
+## child_iter = self.sources.iter_nth_child(selection_iter, i)
+## if child_iter != None:
+## child_node = self.sources.get_value(child_iter, 2)
+## if child_node == filepath:
+## flag = self.sources.remove(child_iter)
+## if flag: # break out if flag is true
+## flag = False
+## else:
+## break
+## i = i + 1
+## os.mkdir(filepath)
+## dialog.destroy()
+
+
+## @exceptions
+## def cb_delete(self, menuitem, data=None):
+## """!
+## Event handler for 'Delete'. This method will delete the file from the
+## filesystem.
+## @param menuitem that threw the event.
+## @param data optional to pass in.
+## """
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## selected_node = self.sources.get_value(selection_iter, 2)
+## os.system('rm ' + selected_node)
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nDeleted ' + selected_node + '.\n')
+
+
+## @exceptions
+## def cb_delete_folder(self, widget):
+## """!
+## Event occurs when the user chooses to delete a folder from the project.
+## This method will delete the folder from the filesystem.
+## @param widget that threw the event.
+## """
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## selected_node = self.sources.get_value(selection_iter, 2)
+## exists = os.path.exists(selected_node)
+## if exists: # delete directory recursively
+## os.system('rm -rf ' + selected_node)
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nDeleted ' + selected_node + '.\n')
+
+
+## @exceptions
+## def cb_open_in_editor(self, action):
+## """!
+## Event occurs when the user wants to open a source file in the editor.
+## @param action gtk.Action object involved with this event
+## """
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## selected_node = self.sources.get_value(selection_iter, 2)
+## # Run the command as if the file is a text file
+## self.utils.run_command(self, selected_node, None, 'txt')
+
+
+## @exceptions
+## def cb_rename_folder(self, action):
+## """!
+## Event handler for renaming a folder.
+## @param action gtk.Action object involved with this event
+## """
+## def response_to_dialog(entry, dialog, response):
+## dialog.response(response)
+
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## old_path = self.sources.get_value(selection_iter, 2)
+## path = self.sources.get_path(selection_iter)
+
+## dialog = gtk.MessageDialog(self.window,
+## (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+## gtk.MESSAGE_QUESTION,
+## gtk.BUTTONS_OK_CANCEL,
+## gtk.STOCK_DIRECTORY)
+## dialog.set_markup('<b>Please enter the new folder name:\n</b>')
+## entry = gtk.Entry()
+## entry.show()
+## entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+## hbox = gtk.HBox()
+## hbox.show()
+## hbox.pack_end(entry)
+## dialog.vbox.pack_end(hbox, True, True, 0)
+## dialog.show()
+## dialog.run()
+## new_text = entry.get_text()
+## dialog.destroy()
+## new_path = old_path.rpartition('/')[0] + '/' + new_text
+
+## if '.' not in new_text:
+## ## We are going to handle the project folder in cb_rename_folder
+## if old_path == self.project.directory:
+## # Project Folder
+## os.rename(old_path, new_path)
+## project_file = new_path + '/' + self.project.name + '.gm'
+## os.remove(project_file)
+## self.project.directory = new_path
+## self.project.name = new_text
+## ## self.project.file_list[0] = new_text
+## ## self.project.file_list[1][0] = new_text + '.gm'
+## self.project.save()
+## self.output_textbuffer.insert(self.output_textiter, 'Project changed from ' + old_path + ' to ' + new_path + '.\n')
+## else:
+## # Regular folder
+## if os.path.exists(new_path):
+## self.output_textbuffer.insert(self.output_textiter, 'Folder already exists with this name. Cannot rename.\n')
+## return
+## os.rename(old_path, new_path)
+
+
+## @exceptions
+## def cb_rename(self, action):
+## """!
+## Event handler for renaming a file.
+## @param action gtk.Action object involved with this event
+## """
+## def response_to_dialog(entry, dialog, response):
+## dialog.response(response)
+
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## old_path = self.sources.get_value(selection_iter, 2)
+## path = self.sources.get_path(selection_iter)
+
+## dialog = gtk.MessageDialog(self.window,
+## (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+## gtk.MESSAGE_QUESTION,
+## gtk.BUTTONS_OK_CANCEL,
+## gtk.STOCK_DIRECTORY)
+## dialog.set_markup('<b>Please enter the new name\n(including extension if applicable):</b>')
+## entry = gtk.Entry()
+## entry.show()
+## entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+## hbox = gtk.HBox()
+## hbox.show()
+## hbox.pack_end(entry)
+## dialog.vbox.pack_end(hbox, True, True, 0)
+## dialog.show()
+## dialog.run()
+## new_text = entry.get_text()
+## dialog.destroy()
+## new_path = old_path.rpartition('/')[0] + '/' + new_text
+
+## if '.' in new_text and '.' in old_path:
+## # File
+## os.rename(old_path, new_path)
+## self.output_textbuffer.insert(self.output_textiter, old_path + ' changed to ' + new_path + '.\n')
+## elif not '.' in new_text and not '.' in old_path:
+## # Folder -- so image does not need to be changed
+## if os.path.exists(new_path):
+## self.output_textbuffer.insert(self.output_textiter, 'Folder already exists with this name. Cannot rename.\n')
+## return
+## os.rename(old_path, new_path)
+## self.output_textbuffer.insert(self.output_textiter, old_path + ' changed to ' + new_path + '.\n')
+
+
+## @exceptions
+## def cb_cursor_changed(self, widget):
+## """!
+## Event occurs when the cursor changes in the treeview.
+## @param widget widget that threw the event
+## """
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## selected_node = self.sources.get_value(selection_iter, 2)
+## filename = self.utils.get_filename_from_filepath(selected_node)
+## if '.' in filename and not filename.endswith(('.gm','.log')):
+## # Logic to call function to find what type of file it is
+## # and then to populate the according tree view
+## ext = filename.split('.')[-1]
+## self.utils.get_processes_tree(self, selected_node, ext, None, True)
+## # Update 'Processes: ' for the 'Processes' tree
+## column = self.processes_tree.get_column(0)
+## column.set_title('Processes for: ' + filename)
+## column = self.processes_tree.get_column(2)
+## column.set_title('status')
+## else: # We have the project folder
+## # Clear out the columns
+## column = self.processes_tree.get_column(0)
+## column.set_title('')
+## column = self.processes_tree.get_column(2)
+## column.set_title('')
+## # clear out the processes
+## self.processes.clear()
+
+
+## def cb_row_changed(self, model, path, iter):
+## """!
+## Event occurs when the columns change in the dependencies treeview.
+## @param model gtk.TreeStore model for the dependencies
+## """
+## print 'starting cb_row_changed'
+## # We only want a file to appear once
+## def recurse_model(row_iter, row):
+## try:
+## for new_row in row_iter:
+## if new_row[1] not in files:
+## # new_dep_list[new_row[1]] = []
+## new_dep_list[row[1]].append(new_row[1])
+## files.append(new_row[1])
+## new_row_iter = new_row.iterchildren()
+## if new_row_iter != None:
+## recurse_model(new_row_iter, new_row)
+## except StopIteration:
+## print 'StopIteraion'
+## except:
+## print 'except:', sys.exc_info()[0]
+
+## files = []
+## new_dep_list = {}
+## for row in model:
+## if row[1] not in files:
+## new_dep_list[row[1]] = []
+## files.append(row[1])
+## row_iter = row.iterchildren()
+## if row_iter != None:
+## recurse_model(row_iter, row)
+
+
+## print 'files:',files
+## print 'new_dep_list:',new_dep_list
+## self.project.dependency_list = new_dep_list
+
+
+## @exceptions
+## def cb_switch_page(self, notebook, page, page_num):
+## if page_num == 1: # Dependencies notebook tab
+## selection = self.sources_tree.get_selection()
+## selection.unselect_all()
+## self.processes.clear()
+## column = self.processes_tree.get_column(0)
+## column.set_title('')
+## column = self.processes_tree.get_column(2)
+## column.set_title('')
+
+
+## @exceptions
+## def cb_popup_deactivate(self, popup_menu, merge_id):
+## """!
+## Event occurs when the 'deactivate' signal is thrown from
+## the popup menu.
+## @param popup_menu is the popup_menu.
+## @param merge_id is the merge id from the popup uimanager.
+## """
+## # Remove the ui from the uimanager
+## self.popup_uimanager.remove_ui(merge_id)
+
+
+## @exceptions
+## def cb_button_press(self, widget, event):
+## """!
+## This signal handler will be called when the treeview emits
+## a 'button_press_event' signal.
+## @param widget widget that threw the event
+## @param event event that was thrown
+## """
+## if event.button == 3:
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## selected_node = self.sources.get_value(selection_iter, 2)
+## else:
+## return
+## popup_menu = gtk.Menu()
+## actiongroup = gtk.ActionGroup('Popup')
+## actiongroup_list = [('Rename', None, '_Rename', None, None, self.cb_rename),
+## ('Rename Folder', None, '_Rename Folder', None, None, self.cb_rename_folder),
+## ('Open in Editor', None, '_Open in Editor', None, None, self.cb_open_in_editor),
+## ('New Source...', gtk.STOCK_FILE, '_New Source...', None, None, self.cb_new_source),
+## ('Copy Existing Source To Project...', gtk.STOCK_COPY, '_Copy Existing Source To Project...', None, None, self.cb_add_copy_source),
+## ('New Folder', gtk.STOCK_DIRECTORY, 'New _Folder', None, None, self.cb_new_folder),
+## ('Delete', gtk.STOCK_DELETE, '_Delete', '<Control>d', None, self.cb_delete),
+## ('Delete Folder', gtk.STOCK_DELETE, '_Delete Folder', None, None, self.cb_delete_folder),]
+
+
+## actiongroup.add_actions(actiongroup_list)
+## self.popup_uimanager.insert_action_group(actiongroup, 0)
+
+## # Choose Popup Menu
+## if selected_node == self.project.directory:
+## # Project Folder
+## merge_id = self.popup_uimanager.add_ui_from_file(self.utils.directory + '/project_popup.xml')
+## popup_menu = self.popup_uimanager.get_widget('/popup')
+## elif '.' not in selected_node:
+## # Folder
+## merge_id = self.popup_uimanager.add_ui_from_file(self.utils.directory + '/folder_popup.xml')
+## popup_menu = self.popup_uimanager.get_widget('/popup')
+## else:
+## # File
+## if selected_node.endswith('.gm'):
+## return
+## merge_id = self.popup_uimanager.add_ui_from_file(self.utils.directory + '/file_popup.xml')
+## popup_menu = self.popup_uimanager.get_widget('/popup')
+
+## popup_menu.connect('deactivate', self.cb_popup_deactivate, merge_id)
+## popup_menu.show()
+## popup_menu.popup(None, None, None, event.button, event.time)
+
+
+## ## TODO -- combine the next three callbacks in some fashion
+## def cb_exit(self, menuitem, data=None):
+## """!
+## Event handler for 'Exit'.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## self.dependencyloop.kill_thread()
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nExiting gEDA Manager.\n')
+## self.write_logs()
+## self.dependencies.emit('row-changed', None, None)
+## self.project.save()
+## self.save_settings()
+## self.kill_processes()
+## gtk.main_quit()
+
+
+## def cb_vte(self):
+## """
+## Event handler for when the embedded terminal is exited.
+## """
+## self.dependencyloop.kill_thread()
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nExiting gEDA Manager.\n')
+## self.write_logs()
+## self.dependencies.emit('row-changed', None, None)
+## self.project.save()
+## self.save_settings()
+## self.kill_processes()
+## gtk.main_quit()
+
+
+## def cb_destroy(self, event):
+## """!
+## Event handlder when the form is closed in any fashion.
+## @param event event that was thrown
+## """
+## self.dependencyloop.kill_thread()
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nExiting gEDA Manager.\n')
+## self.write_logs()
+## self.dependencies.emit('row-changed', None, None)
+## self.project.save()
+## self.save_settings()
+## self.kill_processes()
+## gtk.main_quit()
+
+## ########################################################
+
+## def main(self):
+## """ Method starts the main loop for gtk. """
+## gtk.main()
+
+
+## if __name__ == "__main__":
+## geda_manager = gEDAManager()
+## geda_manager.main()
+
+
diff --git a/src/gui/NewProject.py b/src/gui/NewProject.py
new file mode 100644
index 0000000..6cd9bea
--- /dev/null
+++ b/src/gui/NewProject.py
@@ -0,0 +1,348 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.gui.NewProject
+#New Project window for the gEDA Manager
+#@author Newell Jensen
+
+import os, sys, gtk
+
+class NewProject:
+ """
+ Window for creating a New Project with
+ the gEDA Manager. This form is called
+ when the user wants to create a new project.
+ """
+ def __init__(self, mw):
+ """!
+ NewProject Constructor.
+ @param gedamanager gEDAManager object that the new project is
+ called from
+ """
+ self.mw = mw
+ self.assistant = gtk.Assistant()
+ self.assistant.connect('close', self.cb_close)
+ self.assistant.connect('apply', self.cb_apply)
+ self.assistant.connect('cancel', self.cb_cancel)
+ self.assistant.set_title('gEDA Manager')
+ self.assistant.set_size_request(400, 300)
+ image = self.assistant.render_icon(gtk.STOCK_NEW, gtk.ICON_SIZE_DIALOG)
+
+ ###############################
+ # Choose project filename page
+ ###############################
+
+ vbox = gtk.VBox()
+ vbox.set_border_width(12)
+ vbox.set_spacing(6)
+ vbox.show()
+ label = gtk.Label('')
+ label.set_markup('<b>Choose project filename</b>')
+ label.set_line_wrap(True)
+ label.set_alignment(0, 0.5)
+ label.show()
+ vbox.pack_start(label, False, False)
+
+ align = gtk.Alignment(0, 0, 1, 1)
+ vbox.pack_start(align, True, True)
+ align.set_padding(12, 12, 12, 12)
+ align.show()
+
+ options = gtk.VBox()
+ options.show()
+ align.add(options)
+
+ table = gtk.Table(2,2)
+ table.show()
+ table.set_col_spacings(6)
+ table.set_row_spacings(6)
+ label = gtk.Label('Project name:')
+ label.set_alignment(0, 0.5)
+ label.show()
+ table.attach(label, 0, 1, 0, 1, gtk.FILL, 0)
+ self.filename = gtk.Entry()
+ self.filename.show()
+ table.attach(self.filename, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, 0)
+ label = gtk.Label('Location:')
+ label.set_alignment(0, 0.5)
+ label.show()
+ table.attach(label, 0, 1, 1, 2, gtk.FILL, 0)
+
+ def cb_filebutton_selection_changed(filechooser):
+ """!
+ Function to handle when the filebutton selection is changed.
+ @param filechooser gtk.FileChooserButton object
+ """
+ os.chdir(self.get_path())
+
+ self.filebutton = gtk.FileChooserButton('Select project location...')
+ self.filebutton.show()
+ self.filebutton.connect('selection-changed',
+ cb_filebutton_selection_changed)
+ self.filebutton.set_local_only(True)
+ self.filebutton.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
+ table.attach(self.filebutton, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND, 0)
+ options.pack_start(table, False, False)
+
+ self.assistant.append_page(vbox)
+ self.assistant.set_page_title(vbox, 'Create a new project')
+ self.assistant.set_page_type(vbox, gtk.ASSISTANT_PAGE_CONTENT)
+ self.assistant.set_page_side_image(vbox, image)
+ self.assistant.set_page_complete(vbox, False)
+ self.filename_page = vbox
+
+ def cb_filename_changed(filename_entry):
+ """!
+ Function to handle when the filename is changed.
+ @param filename_entry text entered for the file and
+ directory to be created
+ """
+ self.assistant.set_page_complete(self.filename_page,
+ (filename_entry != ""))
+
+
+ self.filename.connect('changed', cb_filename_changed)
+
+ ########################
+ # Creation Summary page
+ ########################
+
+ vbox = gtk.VBox()
+ vbox.set_border_width(12)
+ vbox.set_spacing(6)
+ vbox.show()
+ label = gtk.Label('')
+ label.set_markup('<b>Project Summary</b>')
+ label.set_line_wrap(True)
+ label.set_alignment(0, 0.5)
+ label.show()
+ vbox.pack_start(label, False, False)
+
+ align = gtk.Alignment(0, 0, 1, 1)
+ vbox.pack_start(align, True, True)
+ align.set_padding(12, 12, 12, 12)
+ align.show()
+
+ explanation = gtk.VBox()
+ explanation.show()
+ align.add(explanation)
+
+ self.new_directory_frame = gtk.Frame('')
+ self.new_directory_frame.get_label_widget().set_markup('<b>New file and directory to be created:</b>')
+ self.new_directory_frame.set_shadow_type(gtk.SHADOW_NONE)
+ explanation.pack_start(self.new_directory_frame, False, False)
+
+ align = gtk.Alignment(0, 0, 1, 1)
+ align.set_padding(0, 12, 12, 12)
+ align.show()
+ self.new_directory_frame.add(align)
+
+ self.new_directory = gtk.Label()
+ self.new_directory.set_alignment(0, 0.5)
+ self.new_directory.set_padding(0, 12)
+ self.new_directory.show()
+ align.add(self.new_directory)
+
+ self.overwrite_frame = gtk.Frame('')
+ self.overwrite_frame.get_label_widget().set_markup('<b>The following directory would be over written:</b>')
+ self.overwrite_frame.set_shadow_type(gtk.SHADOW_NONE)
+ self.overwrite_frame.show()
+ explanation.pack_start(self.overwrite_frame, False, False)
+
+ align = gtk.Alignment(0, 0, 1, 1)
+ align.set_padding(0, 12, 12, 12)
+ align.show()
+ self.overwrite_frame.add(align)
+
+ vbox1 = gtk.VBox()
+ vbox1.show()
+ align.add(vbox1)
+
+ self.overwrite_list = gtk.Label()
+ self.overwrite_list.set_alignment(0, 0.5)
+ self.overwrite_list.set_padding(0, 12)
+ self.overwrite_list.show()
+ vbox1.pack_start(self.overwrite_list, False, False)
+
+ self.confirm_overwrite = gtk.CheckButton('Confirm overwrite')
+ self.confirm_overwrite.show()
+ vbox1.pack_start(self.confirm_overwrite, False, False)
+
+ def cb_confirm_overwrite_toggled(togglebutton):
+ """!
+ Function is called when there is already a file with the same
+ name as the one that is trying to be created.
+ @param togglebutton widget that is either checked (activated)
+ or not checked (not activated)
+ """
+ confirmed = togglebutton.get_active()
+ self.assistant.set_page_complete(self.summary_page, confirmed)
+
+ self.confirm_overwrite.connect('toggled', cb_confirm_overwrite_toggled)
+
+ self.assistant.append_page(vbox)
+ self.assistant.set_page_title(vbox, 'Create new project')
+ self.assistant.set_page_side_image(vbox, image)
+ self.assistant.set_page_type(vbox, gtk.ASSISTANT_PAGE_CONFIRM)
+ self.assistant.show()
+ self.summary_page = vbox
+
+ def check_directory_overwrite():
+ """!
+ Function to check whether or not the directory to be created
+ already exists.
+ @return list
+ """
+ filename = self.get_filename().split('.')[0]
+ f = os.path.exists(self.get_path() + '/' + filename)
+ new_directory = []
+ overwrite_list = []
+
+ if f:
+ overwrite_list.append(filename)
+ else:
+ new_directory.append(filename)
+ return [new_directory, overwrite_list]
+
+
+ def cb_prepare(assistant, page):
+ """!
+ Function to help setup the assistant summary page.
+ @param assistant gtk.Assistant object
+ @param page one of the pages of the gtk.Assistant object
+ """
+ if page is self.summary_page:
+ # Summary page before creating the new project on disk
+ [new_directory, overwrite_list] = check_directory_overwrite()
+ self.new_directory.set_text('\n'.join(new_directory))
+ self.overwrite_list.set_text('\n'.join(overwrite_list))
+
+ no_new_directory = (new_directory == [])
+ if no_new_directory:
+ self.new_directory_frame.hide_all()
+ else:
+ self.new_directory_frame.show_all()
+
+ no_overwrite = (overwrite_list == [])
+ if no_overwrite:
+ # No files will be overwritten, we are done
+ self.overwrite_frame.hide_all()
+ self.assistant.set_page_complete(self.summary_page, True)
+ else:
+ # Need confirmation before overwriting files
+ self.overwrite_frame.show_all()
+ self.confirm_overwrite.set_active(False)
+
+ self.assistant.connect('prepare', cb_prepare)
+
+
+ ######################################
+ # Callback Methods
+ ######################################
+
+ def cb_close(self, assistant):
+ """!
+ Method is called when the NewProject object is closed.
+ @param assistant gtk.Assistant object
+ """
+ self.assistant.destroy()
+
+ def cb_cancel(self, assistant):
+ """!
+ Method is called when the the user chooses 'cancel'.
+ @param assistant gtk.Assistant object
+ """
+ self.assistant.destroy()
+
+ def cb_apply(self, assistant):
+ """!
+ Method is called when the user chooses 'apply' to create
+ the new project.
+ @param assistant gtk.Assistant object
+ """
+ try:
+ # Set new project attributes
+ self.mw.project.name = self.get_filename().split('.')[0]
+ self.mw.project.directory = self.get_path() + '/' + self.mw.project.name.split('.')[0]
+ self.mw.project.dependency_list = {}
+ self.mw.project.dependency_status = {}
+ # Remove directories with imported remove_tree
+ if self.confirm_overwrite.get_active():
+ shutil.rmtree(self.mw.project.directory)
+
+ os.mkdir(self.mw.project.directory)
+ self.mw.project.create()
+ self.mw.dependencyloop.switch_projects()
+ except IOError, (errno, strerror):
+ md = gtk.MessageDialog(self.assistant,
+ (gtk.DIALOG_MODAL |
+ gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_ERROR,
+ gtk.BUTTONS_OK)
+
+ md.set_markup('<span weight="bold" size="larger">Could not create project</span>\n\nError %i: %s') % (errno, strerror)
+ md.show_all()
+ md.run()
+ md.hide_all()
+ return
+ except:
+ self.mw.errors_textbuffer.insert(self.mw.errors_textiter, 'Unexpected error: ' + str(sys.exc_info()[0]) + '.\n')
+ md = gtk.MessageDialog(self.assistant,
+ (gtk.DIALOG_MODAL |
+ gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_ERROR,
+ gtk.BUTTONS_OK)
+
+ md.set_markup('<span weight="bold" size="larger">Could not create project</span>')
+ md.show_all()
+ md.run()
+ md.hide_all()
+
+
+ ######################################
+ # Methods
+ ######################################
+
+ def get_path(self):
+ """!
+ Method to get path of new project.
+ @return filepath from the filebutton
+ """
+ filepath = self.filebutton.get_filename()
+ return filepath
+
+
+ def get_filename(self):
+ """!
+ Method to get file name of the new project.
+ @return filename for the new project file
+ """
+ filename = self.filename.get_text()
+ if not filename.endswith('.gm'):
+ filename += '.gm'
+ return filename
+
+
+ def main(self):
+ """ Method starts the main loop for gtk. """
+ gtk.main()
+
+
+
diff --git a/src/gui/NewProject.py.~1~ b/src/gui/NewProject.py.~1~
new file mode 100644
index 0000000..31bd3a9
--- /dev/null
+++ b/src/gui/NewProject.py.~1~
@@ -0,0 +1,350 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.gui.NewProject
+#New Project window for the gEDA Manager
+#@author Newell Jensen
+
+import os, sys, pygtk, gtk, yaml, shutil
+pygtk.require('2.0')
+from src.utils.Project import *
+
+class NewProject:
+ """
+ Window for creating a New Project with
+ the gEDA Manager. This form is called
+ when the user wants to create a new project.
+ """
+ def __init__(self, gedamanager):
+ """!
+ NewProject Constructor.
+ @param gedamanager gEDAManager object that the new project is
+ called from
+ """
+ self.gedamanager = gedamanager
+ self.assistant = gtk.Assistant()
+ self.assistant.connect('close', self.cb_close)
+ self.assistant.connect('apply', self.cb_apply)
+ self.assistant.connect('cancel', self.cb_cancel)
+ self.assistant.set_title('gEDA Manager')
+ self.assistant.set_size_request(400, 300)
+ image = self.assistant.render_icon(gtk.STOCK_NEW, gtk.ICON_SIZE_DIALOG)
+
+ ###############################
+ # Choose project filename page
+ ###############################
+
+ vbox = gtk.VBox()
+ vbox.set_border_width(12)
+ vbox.set_spacing(6)
+ vbox.show()
+ label = gtk.Label('')
+ label.set_markup('<b>Choose project filename</b>')
+ label.set_line_wrap(True)
+ label.set_alignment(0, 0.5)
+ label.show()
+ vbox.pack_start(label, False, False)
+
+ align = gtk.Alignment(0, 0, 1, 1)
+ vbox.pack_start(align, True, True)
+ align.set_padding(12, 12, 12, 12)
+ align.show()
+
+ options = gtk.VBox()
+ options.show()
+ align.add(options)
+
+ table = gtk.Table(2,2)
+ table.show()
+ table.set_col_spacings(6)
+ table.set_row_spacings(6)
+ label = gtk.Label('Project name:')
+ label.set_alignment(0, 0.5)
+ label.show()
+ table.attach(label, 0, 1, 0, 1, gtk.FILL, 0)
+ self.filename = gtk.Entry()
+ self.filename.show()
+ table.attach(self.filename, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, 0)
+ label = gtk.Label('Location:')
+ label.set_alignment(0, 0.5)
+ label.show()
+ table.attach(label, 0, 1, 1, 2, gtk.FILL, 0)
+
+ def cb_filebutton_selection_changed(filechooser):
+ """!
+ Function to handle when the filebutton selection is changed.
+ @param filechooser gtk.FileChooserButton object
+ """
+ os.chdir(self.get_path())
+
+ self.filebutton = gtk.FileChooserButton('Select project location...')
+ self.filebutton.show()
+ self.filebutton.connect('selection-changed',
+ cb_filebutton_selection_changed)
+ self.filebutton.set_local_only(True)
+ self.filebutton.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
+ table.attach(self.filebutton, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND, 0)
+ options.pack_start(table, False, False)
+
+ self.assistant.append_page(vbox)
+ self.assistant.set_page_title(vbox, 'Create a new project')
+ self.assistant.set_page_type(vbox, gtk.ASSISTANT_PAGE_CONTENT)
+ self.assistant.set_page_side_image(vbox, image)
+ self.assistant.set_page_complete(vbox, False)
+ self.filename_page = vbox
+
+ def cb_filename_changed(filename_entry):
+ """!
+ Function to handle when the filename is changed.
+ @param filename_entry text entered for the file and
+ directory to be created
+ """
+ self.assistant.set_page_complete(self.filename_page,
+ (filename_entry != ""))
+
+
+ self.filename.connect('changed', cb_filename_changed)
+
+ ########################
+ # Creation Summary page
+ ########################
+
+ vbox = gtk.VBox()
+ vbox.set_border_width(12)
+ vbox.set_spacing(6)
+ vbox.show()
+ label = gtk.Label('')
+ label.set_markup('<b>Project Summary</b>')
+ label.set_line_wrap(True)
+ label.set_alignment(0, 0.5)
+ label.show()
+ vbox.pack_start(label, False, False)
+
+ align = gtk.Alignment(0, 0, 1, 1)
+ vbox.pack_start(align, True, True)
+ align.set_padding(12, 12, 12, 12)
+ align.show()
+
+ explanation = gtk.VBox()
+ explanation.show()
+ align.add(explanation)
+
+ self.new_directory_frame = gtk.Frame('')
+ self.new_directory_frame.get_label_widget().set_markup('<b>New file and directory to be created:</b>')
+ self.new_directory_frame.set_shadow_type(gtk.SHADOW_NONE)
+ explanation.pack_start(self.new_directory_frame, False, False)
+
+ align = gtk.Alignment(0, 0, 1, 1)
+ align.set_padding(0, 12, 12, 12)
+ align.show()
+ self.new_directory_frame.add(align)
+
+ self.new_directory = gtk.Label()
+ self.new_directory.set_alignment(0, 0.5)
+ self.new_directory.set_padding(0, 12)
+ self.new_directory.show()
+ align.add(self.new_directory)
+
+ self.overwrite_frame = gtk.Frame('')
+ self.overwrite_frame.get_label_widget().set_markup('<b>The following directory would be over written:</b>')
+ self.overwrite_frame.set_shadow_type(gtk.SHADOW_NONE)
+ self.overwrite_frame.show()
+ explanation.pack_start(self.overwrite_frame, False, False)
+
+ align = gtk.Alignment(0, 0, 1, 1)
+ align.set_padding(0, 12, 12, 12)
+ align.show()
+ self.overwrite_frame.add(align)
+
+ vbox1 = gtk.VBox()
+ vbox1.show()
+ align.add(vbox1)
+
+ self.overwrite_list = gtk.Label()
+ self.overwrite_list.set_alignment(0, 0.5)
+ self.overwrite_list.set_padding(0, 12)
+ self.overwrite_list.show()
+ vbox1.pack_start(self.overwrite_list, False, False)
+
+ self.confirm_overwrite = gtk.CheckButton('Confirm overwrite')
+ self.confirm_overwrite.show()
+ vbox1.pack_start(self.confirm_overwrite, False, False)
+
+ def cb_confirm_overwrite_toggled(togglebutton):
+ """!
+ Function is called when there is already a file with the same
+ name as the one that is trying to be created.
+ @param togglebutton widget that is either checked (activated)
+ or not checked (not activated)
+ """
+ confirmed = togglebutton.get_active()
+ self.assistant.set_page_complete(self.summary_page, confirmed)
+
+ self.confirm_overwrite.connect('toggled', cb_confirm_overwrite_toggled)
+
+ self.assistant.append_page(vbox)
+ self.assistant.set_page_title(vbox, 'Create new project')
+ self.assistant.set_page_side_image(vbox, image)
+ self.assistant.set_page_type(vbox, gtk.ASSISTANT_PAGE_CONFIRM)
+ self.assistant.show()
+ self.summary_page = vbox
+
+ def check_directory_overwrite():
+ """!
+ Function to check whether or not the directory to be created
+ already exists.
+ @return list
+ """
+ filename = self.get_filename().split('.')[0]
+ f = os.path.exists(self.get_path() + '/' + filename)
+ new_directory = []
+ overwrite_list = []
+
+ if f:
+ overwrite_list.append(filename)
+ else:
+ new_directory.append(filename)
+ return [new_directory, overwrite_list]
+
+
+ def cb_prepare(assistant, page):
+ """!
+ Function to help setup the assistant summary page.
+ @param assistant gtk.Assistant object
+ @param page one of the pages of the gtk.Assistant object
+ """
+ if page is self.summary_page:
+ # Summary page before creating the new project on disk
+ [new_directory, overwrite_list] = check_directory_overwrite()
+ self.new_directory.set_text('\n'.join(new_directory))
+ self.overwrite_list.set_text('\n'.join(overwrite_list))
+
+ no_new_directory = (new_directory == [])
+ if no_new_directory:
+ self.new_directory_frame.hide_all()
+ else:
+ self.new_directory_frame.show_all()
+
+ no_overwrite = (overwrite_list == [])
+ if no_overwrite:
+ # No files will be overwritten, we are done
+ self.overwrite_frame.hide_all()
+ self.assistant.set_page_complete(self.summary_page, True)
+ else:
+ # Need confirmation before overwriting files
+ self.overwrite_frame.show_all()
+ self.confirm_overwrite.set_active(False)
+
+ self.assistant.connect('prepare', cb_prepare)
+
+
+ ######################################
+ # Callback Methods
+ ######################################
+
+ def cb_close(self, assistant):
+ """!
+ Method is called when the NewProject object is closed.
+ @param assistant gtk.Assistant object
+ """
+ self.assistant.destroy()
+
+ def cb_cancel(self, assistant):
+ """!
+ Method is called when the the user chooses 'cancel'.
+ @param assistant gtk.Assistant object
+ """
+ self.assistant.destroy()
+
+ def cb_apply(self, assistant):
+ """!
+ Method is called when the user chooses 'apply' to create
+ the new project.
+ @param assistant gtk.Assistant object
+ """
+ try:
+ # Set new project attributes
+ self.gedamanager.project.name = self.get_filename().split('.')[0]
+ self.gedamanager.project.directory = self.get_path() + '/' + self.gedamanager.project.name.split('.')[0]
+ self.gedamanager.project.dependency_list = {}
+ self.gedamanager.project.dependency_status = {}
+ # Remove directories with imported remove_tree
+ if self.confirm_overwrite.get_active():
+ shutil.rmtree(self.gedamanager.project.directory)
+
+ os.mkdir(self.gedamanager.project.directory)
+ self.gedamanager.project.create()
+ self.gedamanager.dependencyloop.switch_projects()
+ except IOError, (errno, strerror):
+ md = gtk.MessageDialog(self.assistant,
+ (gtk.DIALOG_MODAL |
+ gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_ERROR,
+ gtk.BUTTONS_OK)
+
+ md.set_markup('<span weight="bold" size="larger">Could not create project</span>\n\nError %i: %s') % (errno, strerror)
+ md.show_all()
+ md.run()
+ md.hide_all()
+ return
+ except:
+ self.gedamanager.errors_textbuffer.insert(g.errors_textiter, 'Unexpected error: ' + str(sys.exc_info()[0]) + '.\n')
+ md = gtk.MessageDialog(self.assistant,
+ (gtk.DIALOG_MODAL |
+ gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_ERROR,
+ gtk.BUTTONS_OK)
+
+ md.set_markup('<span weight="bold" size="larger">Could not create project</span>')
+ md.show_all()
+ md.run()
+ md.hide_all()
+
+
+ ######################################
+ # Methods
+ ######################################
+
+ def get_path(self):
+ """!
+ Method to get path of new project.
+ @return filepath from the filebutton
+ """
+ filepath = self.filebutton.get_filename()
+ return filepath
+
+
+ def get_filename(self):
+ """!
+ Method to get file name of the new project.
+ @return filename for the new project file
+ """
+ filename = self.filename.get_text()
+ if not filename.endswith('.gm'):
+ filename += '.gm'
+ return filename
+
+
+ def main(self):
+ """ Method starts the main loop for gtk. """
+ gtk.main()
+
+
+
diff --git a/src/gui/Preferences.py b/src/gui/Preferences.py
new file mode 100644
index 0000000..2d423e9
--- /dev/null
+++ b/src/gui/Preferences.py
@@ -0,0 +1,109 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.gui.Preferences
+#Preferences Window
+#@author Newell Jensen
+
+class Preferences(gtk.Window):
+ """
+ Preferences window that is popped up when a user selects to Edit
+ the Preferences for the gEDA Manager
+ """
+ def __init__(self, gedamanager):
+ """ Preferences Constructor. """
+ gtk.Window.__init__(self, gtk.WINDOW_POPUP)
+ self.connect('destroy', lambda w: gtk.main_quit())
+ combobox = gtk.ComboBox()
+ liststore = gtk.ListStore(str, gtk.gdk.Pixbuf)
+ cell = gtk.CellRendererText()
+ combobox.pack_start(cell)
+ combobox.add_attribute(cell, 'text', 0)
+ pic = gtk.CellRendererPixbuf()
+ combobox.pack_start(pic)
+ combobox.add_attribute(pic, 'pixbuf', 1)
+ self.add(combobox)
+ icon = gtk.IconTheme()
+ for tool in sorted(gedamanager.utils.tools):
+ try:
+ image = icon.load_icon(gedamanager.utils.icon_lut[tool], 22, 0)
+ except KeyError:
+ image = None
+ liststore.append([tool, image])
+ combobox.set_model(liststore)
+ combobox.connect('changed', self.cb_combobox_changed)
+ combobox.set_active(0)
+ self.show_all()
+
+ def cb_combobox_changed(self, combobox):
+ model = combobox.get_model()
+ index = combobox.get_active()
+ if index < 0:
+ return
+ else: # Logic here to call when a new 'tool' is selected in the combobox
+ pass
+ return model[index][0]
+
+
+ ## model = gtk.ListStore(str, gtk.gdk.Pixbuf)
+ ## self.icon_view = gtk.IconView(model)
+ ## self.icon_view.set_text_column(0)
+ ## self.icon_view.set_pixbuf_column(1)
+ ## self.icon_view.set_orientation(gtk.ORIENTATION_VERTICAL)
+ ## self.icon_view.set_selection_mode(gtk.SELECTION_SINGLE)
+ ## self.icon_view.connect('selection-changed', self.on_select, model)
+ ## self.icon_view.set_columns(1)
+ ## self.icon_view.set_item_width(-1)
+ ## self.icon_view.set_size_request(72, -1)
+
+ ## self.content_box = gtk.HBox(False)
+ ## self.content_box.pack_start(self.icon_view, fill=True, expand=False)
+ ## self.icon_view.select_path((0,)) # select a category, will create frame
+ ## self.show_all()
+ ## self.vbox.pack_start(self.content_box)
+ ## self.resize(640, 480)
+ ## self.show_all()
+
+ ## def on_select(self, icon_view, model=None):
+ ## selected = icon_view.get_selected_items()
+ ## if len(selected) == 0: return
+ ## i = selected[0][0]
+ ## category = model[i][0]
+ ## if self.current_frame is not None:
+ ## self.content_box.remove(self.current_frame)
+ ## self.current_frame.destroy()
+ ## self.current_frame = None
+ ## if category == 'General':
+ ## self.current_frame = self.create_general_frame()
+ ## elif category == 'Security':
+ ## self.current_frame = self.create_security_frame()
+ ## self.content_box.pack_end(self.current_frame, fill=True, expand=True)
+ ## self.show_all()
+
+ ## def create_general_frame(self):
+ ## frame = gtk.Frame('General')
+ ## return frame
+
+ ## def create_security_frame(self):
+ ## frame = gtk.Frame('Security')
+ ## return frame
+
+
+
diff --git a/src/gui/Preferences.py.~1~ b/src/gui/Preferences.py.~1~
new file mode 100644
index 0000000..0b24519
--- /dev/null
+++ b/src/gui/Preferences.py.~1~
@@ -0,0 +1,112 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.gui.Preferences
+#Preferences Window
+#@author Newell Jensen
+
+import gtk, pygtk
+pygtk.require('2.0')
+
+class Preferences(gtk.Window):
+ """
+ Preferences window that is popped up when a user selects to Edit
+ the Preferences for the gEDA Manager
+ """
+ def __init__(self, gedamanager):
+ """ Preferences Constructor. """
+ gtk.Window.__init__(self, gtk.WINDOW_POPUP)
+ self.connect('destroy', lambda w: gtk.main_quit())
+ combobox = gtk.ComboBox()
+ liststore = gtk.ListStore(str, gtk.gdk.Pixbuf)
+ cell = gtk.CellRendererText()
+ combobox.pack_start(cell)
+ combobox.add_attribute(cell, 'text', 0)
+ pic = gtk.CellRendererPixbuf()
+ combobox.pack_start(pic)
+ combobox.add_attribute(pic, 'pixbuf', 1)
+ self.add(combobox)
+ icon = gtk.IconTheme()
+ for tool in sorted(gedamanager.utils.tools):
+ try:
+ image = icon.load_icon(gedamanager.utils.icon_lut[tool], 22, 0)
+ except KeyError:
+ image = None
+ liststore.append([tool, image])
+ combobox.set_model(liststore)
+ combobox.connect('changed', self.cb_combobox_changed)
+ combobox.set_active(0)
+ self.show_all()
+
+ def cb_combobox_changed(self, combobox):
+ model = combobox.get_model()
+ index = combobox.get_active()
+ if index < 0:
+ return
+ else: # Logic here to call when a new 'tool' is selected in the combobox
+ pass
+ return model[index][0]
+
+
+ ## model = gtk.ListStore(str, gtk.gdk.Pixbuf)
+ ## self.icon_view = gtk.IconView(model)
+ ## self.icon_view.set_text_column(0)
+ ## self.icon_view.set_pixbuf_column(1)
+ ## self.icon_view.set_orientation(gtk.ORIENTATION_VERTICAL)
+ ## self.icon_view.set_selection_mode(gtk.SELECTION_SINGLE)
+ ## self.icon_view.connect('selection-changed', self.on_select, model)
+ ## self.icon_view.set_columns(1)
+ ## self.icon_view.set_item_width(-1)
+ ## self.icon_view.set_size_request(72, -1)
+
+ ## self.content_box = gtk.HBox(False)
+ ## self.content_box.pack_start(self.icon_view, fill=True, expand=False)
+ ## self.icon_view.select_path((0,)) # select a category, will create frame
+ ## self.show_all()
+ ## self.vbox.pack_start(self.content_box)
+ ## self.resize(640, 480)
+ ## self.show_all()
+
+ ## def on_select(self, icon_view, model=None):
+ ## selected = icon_view.get_selected_items()
+ ## if len(selected) == 0: return
+ ## i = selected[0][0]
+ ## category = model[i][0]
+ ## if self.current_frame is not None:
+ ## self.content_box.remove(self.current_frame)
+ ## self.current_frame.destroy()
+ ## self.current_frame = None
+ ## if category == 'General':
+ ## self.current_frame = self.create_general_frame()
+ ## elif category == 'Security':
+ ## self.current_frame = self.create_security_frame()
+ ## self.content_box.pack_end(self.current_frame, fill=True, expand=True)
+ ## self.show_all()
+
+ ## def create_general_frame(self):
+ ## frame = gtk.Frame('General')
+ ## return frame
+
+ ## def create_security_frame(self):
+ ## frame = gtk.Frame('Security')
+ ## return frame
+
+
+
diff --git a/src/gui/__init__.py b/src/gui/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/gui/new.py.~1~ b/src/gui/new.py.~1~
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/src/gui/new.py.~1~
@@ -0,0 +1,2 @@
+
+
diff --git a/src/gui/new.py.~2~ b/src/gui/new.py.~2~
new file mode 100644
index 0000000..bb6a595
--- /dev/null
+++ b/src/gui/new.py.~2~
@@ -0,0 +1,2007 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+import gtk, pygtk, vte
+pygtk.require('2.0')
+from src.utils.Icons import Icons
+
+class MainWindow(gtk.Window):
+ """
+ Top-level Window for the gEDA Manager.
+ This class takes care of all window logic
+ and communication with lower level objects.
+ """
+ def __init__(self):
+ gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
+ self.no_project_name = 'No project loaded...\n\n Select:\n Project->Open Project\n or Project->New Project'
+ self.icons = Icons()
+ self.settings = Settings()
+ self.utils = Utils()
+ if self.settings.project != None:
+ self.project = Project(self.settings.project)
+ else:
+ self.project = Project()
+
+ self.project.connect('closed', self.cb_project_closed)
+ self.project.connect('saved', self.cb_project_saved)
+ self.project.connect('opened', self.cb_project_opened)
+ self.project.connect('created', self.cb_project_created)
+ self.dependencyloop = DependencyLoop(self)
+ self.connect('destroy', self.cb_destroy)
+ self.set_title('gEDA Manager')
+ self.set_icon_from_file('images/icons/geda-xgsch2pcb-48.png')
+ self.set_size_request(700,500)
+
+ # Create a Menu UIManager and a Popup UIManager
+ self.menu_uimanager = gtk.UIManager()
+ self.popup_uimanager = gtk.UIManager()
+ self.menu_accel_group = self.menu_uimanager.get_accel_group()
+ self.add_accel_group(self.menu_accel_group)
+ self.popup_accel_group = self.popup_uimanager.get_accel_group()
+ self.__init_tools__()
+ self.__init_menus__()
+ self.__init_gui_sections__()
+ self.__init_about_dialog__()
+ self.set_menu_defaults()
+ self.show()
+
+ #####################################################
+ # Initializer Methods -- methods to create the window
+ #####################################################
+
+ def __init_tools__(self):
+ """
+ Method to initialize attributes that will be used for the
+ subprocess instances of the gEDA tools.
+ """
+ # Check if .gmrc has an editor attribute
+ if self.gedamanager.settings.editor != None:
+ tools['editor'] = self.gedamanager.settings.editor
+
+
+ def __init_menus__(self):
+ """ Method to create the menu bar. """
+
+ actiongroup0 = gtk.ActionGroup('gEDAManager')
+ actiongroup0_list = [('Project', None, '_Project'),
+ ('New Project', None, 'Ne_w Project', None, 'Create New Project', cb_new_project),
+ ('Open Project', None, 'Open P_roject', None, 'Open Existing Project', cb_open_project),
+ ('Close Project', None, 'Close Projec_t', None, 'Close Active Project', cb_close_project),
+ ('Exit', gtk.STOCK_QUIT, 'E_xit', '<Control>q', 'Exit gEDA Manager', cb_exit),
+ ('Edit', None, '_Edit'),
+ ('Preferences...', gtk.STOCK_PREFERENCES, 'Pr_eferences', None,
+ 'gEDA Manager Preferences', cb_preferences),
+ ('Help', None, '_Help'),
+ ('gEDA Wiki', None, 'gEDA _Wiki', None, 'Opens link in browser',
+ cb_url_geda_wiki),
+ ('gEDA Documentation', None, 'gEDA _Documentation', None,
+ 'Opens link in browser', cb_url_geda_documentation),
+ ('gEDA Manager Documentation', None, 'gEDA _Manager Blog', None, 'Opens link in browser', cb_url_geda_manager_blog),
+ ('gEDA Manager API Documentation', None, 'gEDA Manager _API Documentation', None, 'Opens link in browser', cb_url_geda_manager_api_documentation),
+ ('Web Resources', None, '_Web Resources'),
+ ('About', gtk.STOCK_ABOUT, '_About', None, 'Extra Information about gEDA and the gEDA Manager', cb_show_about_dialog),]
+
+ actiongroup0.add_actions(actiongroup0_list)
+ self.menu_uimanager.insert_action_group(actiongroup0, 0)
+ merge_id = self.menu_uimanager.add_ui_from_file('src/gui/xml/menu.xml')
+ menubar = self.menu_uimanager.get_widget('/MenuBar')
+ self.vbox1 = gtk.VBox()
+ self.vbox1.show()
+ self.add(self.vbox1)
+ self.vbox1.pack_start(menubar, False, False, 0)
+
+ # Set up tooltips
+ tooltips = gtk.Tooltips()
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/New Project')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/New Project')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/Open Project')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/Open Project')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/Close Project')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Project/Exit')
+ action = self.menu_uimanager.get_action('/MenuBar/Project/Exit')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Edit/Preferences...')
+ action = self.menu_uimanager.get_action('/MenuBar/Edit/Preferences...')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Manager Documentation')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Manager Documentation')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Documentation')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Documentation')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Wiki')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Wiki')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+ widget = self.menu_uimanager.get_widget('/MenuBar/Help/About')
+ action = self.menu_uimanager.get_action('/MenuBar/Help/About')
+ tooltips.set_tip(widget, action.get_property('tooltip'))
+
+
+ def __init_gui_sections__(self):
+ """ Method to create the main gui sections of the top-level window. """
+ # Partitioning the window
+ vpaned = gtk.VPaned()
+ vpaned.set_position(300)
+ self.vbox1.pack_start(vpaned, True, True, 0)
+ vpaned.show()
+
+ # Notebook
+ hpaned = gtk.HPaned() # This is the vpaned for sources and process
+ hpaned.set_position(350)
+ vpaned.pack1(hpaned, True, True)
+ hpaned.show()
+ sources_notebook = gtk.Notebook()
+ sources_notebook.show()
+ processes_notebook = gtk.Notebook()
+ processes_notebook.show()
+ sources_notebook.connect('switch-page', cb_switch_page, self)
+ processes_notebook.connect('switch-page', cb_switch_page, self)
+ hpaned.pack1(sources_notebook, True, True)
+ hpaned.pack2(processes_notebook, True, True)
+ sources_notebook.set_tab_pos(gtk.POS_BOTTOM)
+ processes_notebook.set_tab_pos(gtk.POS_BOTTOM)
+
+ scrolled_window_sources = gtk.ScrolledWindow()
+ scrolled_window_sources.show()
+ scrolled_window_processes = gtk.ScrolledWindow()
+ scrolled_window_processes.show()
+ scrolled_window_dependencies = gtk.ScrolledWindow()
+ scrolled_window_dependencies.show()
+ scrolled_window_sources.set_shadow_type(gtk.SHADOW_IN)
+ scrolled_window_sources.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scrolled_window_processes.set_shadow_type(gtk.SHADOW_IN)
+ scrolled_window_processes.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scrolled_window_dependencies.set_shadow_type(gtk.SHADOW_IN)
+ scrolled_window_dependencies.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+ sources_notebook.add(scrolled_window_sources)
+ processes_notebook.add(scrolled_window_processes)
+ sources_notebook.append_page(scrolled_window_dependencies)
+
+ # Labels
+ sources_label = gtk.Label('Sources')
+ sources_label.show()
+ dependencies_label = gtk.Label('Dependencies')
+ dependencies_label.show()
+ processes_label = gtk.Label('Processes')
+ processes_label.show()
+ sources_notebook.set_tab_label(sources_notebook.get_nth_page(0), sources_label)
+ sources_notebook.set_tab_label(sources_notebook.get_nth_page(1), dependencies_label)
+ processes_notebook.set_tab_label(processes_notebook.get_nth_page(0), processes_label)
+
+ # Models for the Tree Views
+ self.sources = gtk.TreeStore(gtk.gdk.Pixbuf, str, str)
+ self.processes = gtk.TreeStore(str, gtk.gdk.Pixbuf, gtk.gdk.Pixbuf)
+ self.dependencies = gtk.TreeStore(str, str)
+
+ # Source Tree View
+ self.sources_tree = gtk.TreeView(self.sources)
+ self.sources_tree.show()
+ self.sources_tree.connect('button_press_event', cb_button_press, self, self.gedamanager)
+ self.sources_tree.connect('row-activated', cb_sources_row_activated, self, self.gedamanager)
+ self.sources_tree.connect('cursor-changed', cb_cursor_changed, self)
+ column = gtk.TreeViewColumn(None, gtk.CellRendererPixbuf(), pixbuf=0)
+ self.sources_tree.append_column(column)
+ sources_cell = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(None, sources_cell, text=1)
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ self.sources_tree.append_column(column)
+
+ # Processes Tree View
+ self.processes_tree = gtk.TreeView(self.processes)
+ self.processes_tree.show()
+ self.processes_tree.connect('row-activated', cb_processes_row_activated, self)
+ column = gtk.TreeViewColumn('Processes for: ', gtk.CellRendererText(), text=0)
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ self.processes_tree.append_column(column)
+ processes_pixbuf = gtk.CellRendererPixbuf()
+ processes_pixbuf.set_property('xalign', 0.2)
+ column = gtk.TreeViewColumn(None, processes_pixbuf, pixbuf=1)
+ self.processes_tree.append_column(column)
+ column = gtk.TreeViewColumn(None, processes_pixbuf, pixbuf=2)
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ self.processes_tree.append_column(column)
+
+ # Dependencies Tree View
+ self.dependencies_tree = gtk.TreeView(self.dependencies)
+ self.dependencies_tree.show()
+ self.dependencies.connect('row-changed', cb_row_changed, self.gedamanager)
+
+ # create the TreeViewColumn to display the data
+ column = gtk.TreeViewColumn('Files')
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ dependencies_cell = gtk.CellRendererText()
+ column.pack_start(dependencies_cell, True)
+ column.add_attribute(dependencies_cell, 'text', 0)
+
+ # Allow sorting on the column
+ column.set_sort_column_id(0)
+ self.dependencies_tree.append_column(column)
+
+ # enable-tree-lines
+ self.sources_tree.set_property('enable-tree-lines', True)
+ self.processes_tree.set_property('enable-tree-lines', True)
+ self.dependencies_tree.set_property('enable-tree-lines', True)
+
+ # make it searchable
+ self.sources_tree.set_search_column(0)
+ self.processes_tree.set_search_column(0)
+ self.dependencies_tree.set_search_column(0)
+
+ # Allow drag and drop reordering of rows
+ self.dependencies_tree.set_reorderable(True)
+
+ # set tooltip columns
+ self.sources_tree.set_tooltip_column(2)
+ self.dependencies_tree.set_tooltip_column(1)
+
+ # add to the scrolling windows
+ scrolled_window_sources.add(self.sources_tree)
+ scrolled_window_processes.add(self.processes_tree)
+ scrolled_window_dependencies.add(self.dependencies_tree)
+
+ ######################################
+ # Lower Notebook Window
+ ######################################
+
+ notebook = gtk.Notebook()
+ notebook.show()
+ vpaned.pack2(notebook, True, True)
+ notebook.set_tab_pos(gtk.POS_BOTTOM)
+ terminal_scrolled_window = gtk.ScrolledWindow()
+ terminal_scrolled_window.show()
+
+ # Add a terminal to the terminal output notebook
+ current_directory = os.getcwd()
+ try:
+ os.chdir(self.gedamanager.project.directory)
+ except:
+ pass
+ self.terminal = vte.Terminal()
+ self.terminal.connect('child-exited', lambda term: cb_vte())
+ self.terminal.fork_command()
+ self.terminal.show()
+ os.chdir(current_directory)
+ terminal_scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+ terminal_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ terminal_scrolled_window.add_with_viewport(self.terminal)
+ notebook.add(terminal_scrolled_window)
+
+ icon = gtk.IconTheme()
+ terminal_icon = icon.load_icon(self.icons.icon_lut['terminal'], 22, 0)
+ terminal_pixbuf = gtk.Image()
+ terminal_pixbuf.set_from_pixbuf(terminal_icon)
+ notebook.set_tab_label(notebook.get_nth_page(0), terminal_pixbuf)
+
+ output_scolled_window = gtk.ScrolledWindow()
+ output_scolled_window.show()
+ output_scolled_window.set_shadow_type(gtk.SHADOW_IN)
+ output_scolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ notebook.add(output_scolled_window)
+
+ output_textview = gtk.TextView()
+ output_textview.set_editable(False)
+ output_textview.set_cursor_visible(False)
+ self.output_textbuffer = output_textview.get_buffer()
+ self.output_textiter = self.output_textbuffer.get_start_iter()
+ output_textview.show()
+ output_scolled_window.add(output_textview)
+
+ output_icon = icon.load_icon(self.icons.icon_lut['output'], 22, 0)
+ output_pixbuf = gtk.Image()
+ output_pixbuf.set_from_pixbuf(output_icon)
+ notebook.set_tab_label(notebook.get_nth_page(1), output_pixbuf)
+
+ errors_scrolled_window = gtk.ScrolledWindow()
+ errors_scrolled_window.show()
+ errors_scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+ errors_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ notebook.add(errors_scrolled_window)
+
+ errors_textview = gtk.TextView()
+ errors_textview.set_editable(False)
+ errors_textview.set_cursor_visible(False)
+ self.errors_textbuffer = errors_textview.get_buffer()
+ self.errors_textiter = self.errors_textbuffer.get_start_iter()
+ errors_textview.show()
+ errors_scrolled_window.add(errors_textview)
+
+ errors_icon = icon.load_icon(self.icons.icon_lut['errors'], 22, 0)
+ errors_pixbuf = gtk.Image()
+ errors_pixbuf.set_from_pixbuf(errors_icon)
+ notebook.set_tab_label(notebook.get_nth_page(2), errors_pixbuf)
+
+ self.output_textbuffer.insert(self.output_textiter, 'Output log--\n')
+ self.errors_textbuffer.insert(self.errors_textiter, 'Error log--\n')
+
+ # Finally add data to the sources_tree and the dependencies_tree
+ self.set_sources_tree_to_project()
+ self.set_dependencies_tree_to_project()
+
+
+ def __init_about_dialog__(self):
+ """ Method to create the about dialog. """
+
+ def about_url_cb(dialog, link, user_data):
+ """!
+ Call back function to test url for the about dialog
+ @param dialog about dialog object
+ @param link url link that was clicked
+ @param user_data user data that was passed in
+ """
+ gnomevfs.url_show(link)
+
+ self.aboutdialog = gtk.AboutDialog()
+ self.aboutdialog.set_name("gEDA Manager")
+ self.aboutdialog.set_license(__doc__)
+ self.aboutdialog.set_version(str(self.gedamanager.settings.version))
+ self.aboutdialog.set_copyright("gEDA Manager 2008")
+ self.aboutdialog.set_authors(['Newell Jensen', '--',
+ 'Before Enlightenment, chop wood and carry water',
+ 'After Enlightenment, code and build circuits'])
+ gtk.about_dialog_set_url_hook(about_url_cb, None)
+ self.aboutdialog.set_website('http://geda.seul.org')
+ self.aboutdialog.set_translator_credits('translator-credits')
+ self.aboutdialog.set_transient_for(self)
+
+
+ ## ####################################
+ ## # Methods
+ ## ####################################
+
+ ## def set_menu_defaults(self):
+ ## """
+ ## Method to coordiante which methods should be called to handle
+ ## the sensitivity of the menu items.
+ ## """
+ ## # Project
+ ## if self.gedamanager.project.name == None or self.gedamanager.project.name == self.gedamanager.no_project_name:
+ ## self.set_no_project_default()
+ ## else:
+ ## self.set_project_default()
+
+
+ ## def set_no_project_default(self):
+ ## """
+ ## Method to set the default sensitivity when no project is loaded.
+ ## """
+ ## # File Menu
+ ## self.gedamanager.project.name = self.no_project_name
+ ## self.sources_tree.set_property('headers-visible', True)
+ ## column = self.sources_tree.get_column(0)
+ ## column.set_title(self.gedamanager.project.name)
+ ## save_project_as_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Save Project As...')
+ ## close_project_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+ ## close_project_menuitem.set_sensitive(False)
+
+
+ ## def set_project_default(self):
+ ## """
+ ## Method to set the default sensitivity when a project is loaded.
+ ## """
+ ## # File Menu
+ ## self.sources_tree.set_property('headers-visible', False)
+ ## save_project_as_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Save Project As...')
+ ## close_project_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+ ## close_project_menuitem.set_sensitive(True)
+
+
+ ## def set_project(self, path):
+ ## """!
+ ## Method to set current project to the one on path.
+ ## @param path path for project to open.
+ ## """
+ ## # Save current project
+ ## if not self.gedamanager.project.clean:
+ ## self.gedamanager.project.save()
+ ## self.gedamanager.project.open(path)
+ ## self.output_textbuffer.insert(self.output_textiter, get_time() + ':\n' + 'Project set to ' + self.gedamanager.project.name + '\n')
+ ## self.dependencyloop.switch_projects()
+
+
+ ## def set_sources_tree_to_project(self):
+ ## """ Method to set the tree to current project object. """
+ ## self.sources.clear()
+ ## if self.gedamanager.project.name != None:
+ ## self.load_sources_tree()
+ ## self.sources_tree.expand_all()
+
+
+ ## def set_dependencies_tree_to_project(self):
+ ## """ Method to set the tree to current project object. """
+ ## self.dependencies.clear()
+ ## if self.gedamanager.project.dependency_list != None:
+ ## self.load_dependencies_tree()
+ ## self.dependencies_tree.expand_all()
+
+
+ ## def set_dependencies_tree_to_new_project(self):
+ ## """ Method to set the tree to newly created project object. """
+ ## #self.dependencyloop.switch_projects()
+ ## self.dependencies.clear()
+ ## # Parent Folder
+ ## project_path = self.gedamanager.project.directory + '/' + self.gedamanager.project.name
+ ## project_file_path = project_path + '.gm'
+ ## output_file_path = self.gedamanager.project.directory + '/output.log'
+ ## error_file_path = self.gedamanager.project.directory + '/error.log'
+
+
+ ## def load_sources_tree(self):
+ ## """
+ ## Method to the load the 'Sources' TreeView from the
+ ## directory structure of the project.
+ ## """
+ ## if self.sources != None:
+ ## # Clear out the sources first
+ ## self.sources.clear()
+ ## # Start adding data to the Model
+ ## if isinstance(self.gedamanager.project.directory, str):
+ ## if os.path.exists(self.gedamanager.project.directory):
+ ## os.chdir(self.gedamanager.project.directory)
+ ## node = None
+ ## dictionary = {}
+ ## icon = gtk.IconTheme() # The icon used throughout the function
+ ## for root, dirs, files in os.walk(self.gedamanager.project.directory):
+ ## if root == self.gedamanager.project.directory:
+ ## image = icon.load_icon(self.icons.icon_lut['project'], 22, 0)
+ ## else:
+ ## image = icon.load_icon(self.icons.icon_lut['folder'], 22, 0)
+
+ ## folder = root.split('/')[-1]
+ ## try:
+ ## node = self.sources.append(dictionary[root], [image, folder, root])
+ ## except KeyError:
+ ## node = self.sources.append(None, [image, folder, root])
+ ## for f in [name for dec,name in sorted((os.path.splitext(f)[1][1:],f) for f in files)]: # List expression sorts by file extension
+ ## if not f.endswith(('~','-','#')):
+ ## image = icon.load_icon(self.icons.load_image(f), 22, 0)
+ ## self.sources.append(node, [image, f, os.path.join(root, f)])
+ ## for d in dirs:
+ ## dictionary[os.path.join(root, d)] = node
+
+ ## self.sources_tree.expand_all()
+
+
+ ## def load_dependencies_tree(self):
+ ## """!
+ ## Method to the load the dependencies tree
+ ## """
+ ## # Need to add checking for whether or not the filesystem still
+ ## # has the files before appending them to self.dependencies
+
+ ## # Either this or have a function that I call before this one that
+ ## # straightens it all out by going over the dependency_list and making
+ ## # sure that these files are the correct ones and if not it can call
+ ## # the functions remove/add/update_dependency() functions
+ ## def recurse_dependencies(dep_list, parent):
+ ## for value in dep_list:
+ ## filename = get_filename_from_filepath(value)
+ ## n_parent = self.dependenices.append(parent, [filename, value])
+ ## # recurse
+ ## if self.gedamanager.project.dependency_list[value] != []:
+ ## recurse_dependencies(self.gedamanager.project.dependency_list[value], n_parent)
+
+ ## if self.dependencies != None:
+ ## self.dependencies.clear()
+ ## for key, value in self.gedamanager.project.dependency_list.iteritems():
+ ## filename = get_filename_from_filepath(key)
+ ## n_parent = self.dependencies.append(None, [filename, key])
+ ## # recurse
+ ## if self.gedamanager.project.dependency_list[key] != []:
+ ## recurse_dependencies(value, n_parent)
+
+
+ ## def update_dependency(self, pathname, recurse=False):
+ ## # First, make sure that the file is already in the dependencies
+ ## if self.gedamanager.project.dependency_status != None:
+ ## try:
+ ## if not recurse:
+ ## self.gedamanager.project.dependency_status[pathname] = True
+ ## else:
+ ## self.gedamanager.project.dependency_status[pathname] = False
+ ## # recurse over the dependency_list
+ ## if self.gedamanager.project.dependency_list != None:
+ ## for value in self.gedamanager.project.dependency_list[pathname]:
+ ## self.update_dependency(value, True)
+ ## except KeyError:
+ ## print 'KeyError_update'
+ ## finally:
+ ## self.gedamanager.project.save()
+ ## self.load_dependencies_tree()
+
+
+ ## def add_dependency(self, pathname):
+ ## print 'in add_dependency'
+ ## try:
+ ## if self.gedamanager.project.dependency_list != None:
+ ## self.gedamanager.project.dependency_list[pathname] = []
+ ## if self.gedamanager.project.dependency_status != None:
+ ## self.gedamanager.project.dependency_status[pathname] = True
+ ## except KeyError:
+ ## print 'KeyError_add'
+ ## finally:
+ ## self.gedamanager.project.save()
+ ## self.load_dependencies_tree()
+
+
+ ## def remove_dependency(self, pathname, recurse=False):
+ ## # First, make sure that the file is already in the dependencies
+ ## if self.gedamanager.project.dependency_status != None:
+ ## if pathname in self.gedamanager.project.dependency_status:
+ ## try:
+ ## # iterate over the dependencies and flatten
+ ## for value in self.gedamanager.project.dependency_list[pathname]:
+ ## self.remove_dependency(value, True)
+ ## self.gedamanager.project.dependency_list[pathname] = []
+ ## except KeyError:
+ ## print 'KeyError_remove'
+ ## finally:
+ ## if not recurse:
+ ## del self.gedamanager.project.dependency_status[pathname]
+ ## del self.gedamanager.project.dependency_list[pathname]
+ ## else:
+ ## self.gedamanager.project.dependency_status[pathname] = False
+ ## self.gedamanager.project.save()
+ ## self.load_dependencies_tree()
+
+
+ ## def get_processes_selected_node(self):
+ ## """!
+ ## Method to get the selected node in the 'Processes' treeview.
+ ## @return path of the selected node
+ ## """
+ ## selection = self.processes_tree.get_selection()
+ ## model, selection_iter = selection.get_selected()
+ ## if isinstance(selection_iter, gtk.TreeIter):
+ ## return self.processes.get_value(selection_iter, 2)
+ ## else:
+ ## return None
+
+
+ ## def file_filters(self, dialog):
+ ## """!
+ ## Method to abstract some redundant code that is used in the message
+ ## dialog boxes.
+ ## @param dialog gtk.FileChooserDialog object
+ ## """
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("All files")
+ ## file_filter.add_pattern('*')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("schematics (.sch)")
+ ## file_filter.add_pattern('*.sch')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("symbols (.sym)")
+ ## file_filter.add_pattern('*.sym')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("pcb (.pcb)")
+ ## file_filter.add_pattern('*.pcb')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("verilog (.v)")
+ ## file_filter.add_pattern('*.v')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("vhdl (.vhd)")
+ ## file_filter.add_pattern('*.vhd')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("bom (.bom)")
+ ## file_filter.add_pattern('*.bom')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("drc (.drc)")
+ ## file_filter.add_pattern('*.drc')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("gerber (.gbr)")
+ ## file_filter.add_pattern('*.gbr')
+ ## dialog.add_filter(file_filter)
+
+ ## file_filter = gtk.FileFilter()
+ ## file_filter.set_name("spice (.spice)")
+ ## file_filter.add_pattern('*.spice')
+ ## dialog.add_filter(file_filter)
+
+
+#old
+## ###########################################################################
+## def __init_menus__(self):
+## """ Method to create the menu bar. """
+
+## actiongroup0 = gtk.ActionGroup('gEDAManager')
+## actiongroup0_list = [('Project', None, '_Project'),
+## ('New Project', None, 'Ne_w Project', None, 'Create New Project', self.cb_new_project),
+## ('Open Project', None, 'Open P_roject', None, 'Open Existing Project', self.cb_open_project),
+## ('Close Project', None, 'Close Projec_t', None, 'Close Active Project', self.cb_close_project),
+## ('Exit', gtk.STOCK_QUIT, 'E_xit', '<Control>q', 'Exit gEDA Manager', self.cb_exit),
+## ('Edit', None, '_Edit'),
+## ('Preferences...', gtk.STOCK_PREFERENCES, 'Pr_eferences', None,
+## 'gEDA Manager Preferences', self.cb_preferences),
+## ('Help', None, '_Help'),
+## ('gEDA Wiki', None, 'gEDA _Wiki', None, 'Opens link in browser',
+## self.cb_url_geda_wiki),
+## ('gEDA Documentation', None, 'gEDA _Documentation', None,
+## 'Opens link in browser', self.cb_url_geda_documentation),
+## ('gEDA Manager Documentation', None, 'gEDA _Manager Blog', None, 'Opens link in browser', self.cb_url_geda_manager_blog),
+## ('gEDA Manager API Documentation', None, 'gEDA Manager _API Documentation', None, 'Opens link in browser', self.cb_url_geda_manager_api_documentation),
+## ('Web Resources', None, '_Web Resources'),
+## ('About', gtk.STOCK_ABOUT, '_About', None, 'Extra Information about gEDA and the gEDA Manager', self.cb_show_about_dialog),]
+
+## actiongroup0.add_actions(actiongroup0_list)
+## self.menu_uimanager.insert_action_group(actiongroup0, 0)
+## merge_id = self.menu_uimanager.add_ui_from_file('menu.xml')
+## menubar = self.menu_uimanager.get_widget('/MenuBar')
+## self.vbox1 = gtk.VBox()
+## self.vbox1.show()
+## self.window.add(self.vbox1)
+## self.vbox1.pack_start(menubar, False, False, 0)
+
+## # Set up tooltips
+## tooltips = gtk.Tooltips()
+## widget = self.menu_uimanager.get_widget('/MenuBar/Project/New Project')
+## action = self.menu_uimanager.get_action('/MenuBar/Project/New Project')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Project/Open Project')
+## action = self.menu_uimanager.get_action('/MenuBar/Project/Open Project')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+## action = self.menu_uimanager.get_action('/MenuBar/Project/Close Project')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Project/Exit')
+## action = self.menu_uimanager.get_action('/MenuBar/Project/Exit')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Edit/Preferences...')
+## action = self.menu_uimanager.get_action('/MenuBar/Edit/Preferences...')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Manager Documentation')
+## action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Manager Documentation')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Documentation')
+## action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Documentation')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Help/Web Resources/gEDA Wiki')
+## action = self.menu_uimanager.get_action('/MenuBar/Help/Web Resources/gEDA Wiki')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+## widget = self.menu_uimanager.get_widget('/MenuBar/Help/About')
+## action = self.menu_uimanager.get_action('/MenuBar/Help/About')
+## tooltips.set_tip(widget, action.get_property('tooltip'))
+
+
+## def __init_gui_sections__(self):
+## """ Method to create the main gui sections of the top-level window. """
+## # Partitioning the window
+## hpaned = gtk.HPaned()
+## hpaned.set_position(400)
+## self.vbox1.pack_start(hpaned, True, True, 0)
+## hpaned.show()
+
+## # Notebook
+## vpaned = gtk.VPaned() # This is the vpaned for sources and process
+## hpaned.pack1(vpaned, True, True)
+## vpaned.show()
+## sources_notebook = gtk.Notebook()
+## sources_notebook.show()
+## processes_notebook = gtk.Notebook()
+## processes_notebook.show()
+## sources_notebook.connect('switch-page', self.cb_switch_page)
+## processes_notebook.connect('switch-page', self.cb_switch_page)
+## vpaned.pack1(sources_notebook, True, True)
+## vpaned.pack2(processes_notebook, True, True)
+## sources_notebook.set_tab_pos(gtk.POS_BOTTOM)
+## processes_notebook.set_tab_pos(gtk.POS_BOTTOM)
+
+## scrolled_window_sources = gtk.ScrolledWindow()
+## scrolled_window_sources.show()
+## scrolled_window_processes = gtk.ScrolledWindow()
+## scrolled_window_processes.show()
+## scrolled_window_dependencies = gtk.ScrolledWindow()
+## scrolled_window_dependencies.show()
+## scrolled_window_sources.set_shadow_type(gtk.SHADOW_IN)
+## scrolled_window_sources.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+## scrolled_window_processes.set_shadow_type(gtk.SHADOW_IN)
+## scrolled_window_processes.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+## scrolled_window_dependencies.set_shadow_type(gtk.SHADOW_IN)
+## scrolled_window_dependencies.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+## sources_notebook.add(scrolled_window_sources)
+## processes_notebook.add(scrolled_window_processes)
+## sources_notebook.append_page(scrolled_window_dependencies)
+
+## # Labels
+## sources_label = gtk.Label('Sources')
+## sources_label.show()
+## dependencies_label = gtk.Label('Dependencies')
+## dependencies_label.show()
+## processes_label = gtk.Label('Processes')
+## processes_label.show()
+## sources_notebook.set_tab_label(sources_notebook.get_nth_page(0), sources_label)
+## sources_notebook.set_tab_label(sources_notebook.get_nth_page(1), dependencies_label)
+## processes_notebook.set_tab_label(processes_notebook.get_nth_page(0), processes_label)
+
+## # Models for the Tree Views
+## self.sources = gtk.TreeStore(gtk.gdk.Pixbuf, str, str)
+## self.processes = gtk.TreeStore(str, gtk.gdk.Pixbuf, gtk.gdk.Pixbuf)
+## self.dependencies = gtk.TreeStore(str, str)
+
+## # Source Tree View
+## self.sources_tree = gtk.TreeView(self.sources)
+## self.sources_tree.show()
+## self.sources_tree.connect('button_press_event', self.cb_button_press)
+## self.sources_tree.connect('row-activated', self.utils.cb_sources_row_activated, self)
+## self.sources_tree.connect('cursor-changed', self.cb_cursor_changed)
+## column = gtk.TreeViewColumn(None, gtk.CellRendererPixbuf(), pixbuf=0)
+## self.sources_tree.append_column(column)
+## sources_cell = gtk.CellRendererText()
+## column = gtk.TreeViewColumn(None, sources_cell, text=1)
+## column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+## self.sources_tree.append_column(column)
+
+## # Processes Tree View
+## self.processes_tree = gtk.TreeView(self.processes)
+## self.processes_tree.show()
+## self.processes_tree.connect('row-activated', self.utils.cb_processes_row_activated, self)
+## column = gtk.TreeViewColumn('Processes for: ', gtk.CellRendererText(), text=0)
+## column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+## self.processes_tree.append_column(column)
+## processes_pixbuf = gtk.CellRendererPixbuf()
+## processes_pixbuf.set_property('xalign', 0.2)
+## column = gtk.TreeViewColumn(None, processes_pixbuf, pixbuf=1)
+## self.processes_tree.append_column(column)
+## column = gtk.TreeViewColumn(None, processes_pixbuf, pixbuf=2)
+## column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+## self.processes_tree.append_column(column)
+
+## # Dependencies Tree View
+## self.dependencies_tree = gtk.TreeView(self.dependencies)
+## self.dependencies_tree.show()
+## self.dependencies.connect('row-changed', self.cb_row_changed)
+
+## # create the TreeViewColumn to display the data
+## column = gtk.TreeViewColumn('Files')
+## column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+## dependencies_cell = gtk.CellRendererText()
+## column.pack_start(dependencies_cell, True)
+## column.add_attribute(dependencies_cell, 'text', 0)
+
+## # Allow sorting on the column
+## column.set_sort_column_id(0)
+## self.dependencies_tree.append_column(column)
+
+## # enable-tree-lines
+## self.sources_tree.set_property('enable-tree-lines', True)
+## self.processes_tree.set_property('enable-tree-lines', True)
+## self.dependencies_tree.set_property('enable-tree-lines', True)
+
+## # make it searchable
+## self.sources_tree.set_search_column(0)
+## self.processes_tree.set_search_column(0)
+## self.dependencies_tree.set_search_column(0)
+
+## # Allow drag and drop reordering of rows
+## self.dependencies_tree.set_reorderable(True)
+## self.sources_tree.set_reorderable(True)
+
+## # set tooltip columns
+## self.sources_tree.set_tooltip_column(2)
+## self.dependencies_tree.set_tooltip_column(1)
+
+## # add to the scrolling windows
+## scrolled_window_sources.add(self.sources_tree)
+## scrolled_window_processes.add(self.processes_tree)
+## scrolled_window_dependencies.add(self.dependencies_tree)
+
+## ######################################
+## # Lower Notebook Window
+## ######################################
+
+## notebook = gtk.Notebook()
+## notebook.show()
+## hpaned.pack2(notebook, True, True)
+## notebook.set_tab_pos(gtk.POS_BOTTOM)
+## terminal_scrolled_window = gtk.ScrolledWindow()
+## terminal_scrolled_window.show()
+
+## # Add a terminal to the terminal output notebook
+## current_directory = os.getcwd()
+## try:
+## os.chdir(self.project.directory)
+## except:
+## pass
+## self.terminal = vte.Terminal()
+## self.terminal.connect('child-exited', lambda term: self.cb_vte())#lambda term: gtk.main_quit())
+## self.terminal.fork_command()
+## self.terminal.show()
+## os.chdir(current_directory)
+## terminal_scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+## terminal_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+## terminal_scrolled_window.add_with_viewport(self.terminal)
+## notebook.add(terminal_scrolled_window)
+
+## icon = gtk.IconTheme()
+## terminal_icon = icon.load_icon(self.utils.icon_lut['terminal'], 22, 0)
+## terminal_pixbuf = gtk.Image()
+## terminal_pixbuf.set_from_pixbuf(terminal_icon)
+## notebook.set_tab_label(notebook.get_nth_page(0), terminal_pixbuf)
+
+## output_scolled_window = gtk.ScrolledWindow()
+## output_scolled_window.show()
+## output_scolled_window.set_shadow_type(gtk.SHADOW_IN)
+## output_scolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+## notebook.add(output_scolled_window)
+
+## output_textview = gtk.TextView()
+## output_textview.set_editable(False)
+## output_textview.set_cursor_visible(False)
+## self.output_textbuffer = output_textview.get_buffer()
+## self.output_textiter = self.output_textbuffer.get_start_iter()
+## output_textview.show()
+## output_scolled_window.add(output_textview)
+
+## output_icon = icon.load_icon(self.utils.icon_lut['output'], 22, 0)
+## output_pixbuf = gtk.Image()
+## output_pixbuf.set_from_pixbuf(output_icon)
+## notebook.set_tab_label(notebook.get_nth_page(1), output_pixbuf)
+
+## errors_scrolled_window = gtk.ScrolledWindow()
+## errors_scrolled_window.show()
+## errors_scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+## errors_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+## notebook.add(errors_scrolled_window)
+
+## errors_textview = gtk.TextView()
+## errors_textview.set_editable(False)
+## errors_textview.set_cursor_visible(False)
+## self.errors_textbuffer = errors_textview.get_buffer()
+## self.errors_textiter = self.errors_textbuffer.get_start_iter()
+## errors_textview.show()
+## errors_scrolled_window.add(errors_textview)
+
+## errors_icon = icon.load_icon(self.utils.icon_lut['errors'], 22, 0)
+## errors_pixbuf = gtk.Image()
+## errors_pixbuf.set_from_pixbuf(errors_icon)
+## notebook.set_tab_label(notebook.get_nth_page(2), errors_pixbuf)
+
+## self.output_textbuffer.insert(self.output_textiter, 'Output log--\n')
+## self.errors_textbuffer.insert(self.errors_textiter, 'Error log--\n')
+
+## # Finally add data to the sources_tree and the dependencies_tree
+## self.set_sources_tree_to_project()
+## self.set_dependencies_tree_to_project()
+
+
+## def __init_about_dialog__(self):
+## """ Method to create the about dialog. """
+
+## def about_url_cb(dialog, link, user_data):
+## """!
+## Call back function to test url for the about dialog
+## @param dialog about dialog object
+## @param link url link that was clicked
+## @param user_data user data that was passed in
+## """
+## gnomevfs.url_show(link)
+
+## self.aboutdialog = gtk.AboutDialog()
+## self.aboutdialog.set_name("gEDA Manager")
+## self.aboutdialog.set_license(__doc__)
+## self.aboutdialog.set_version(str(self.settings.version))
+## self.aboutdialog.set_copyright("gEDA Manager 2008")
+## self.aboutdialog.set_authors(['Newell Jensen', '--',
+## 'Before Enlightenment, chop wood and carry water',
+## 'After Enlightenment, code and build circuits'])
+## gtk.about_dialog_set_url_hook(about_url_cb, None)
+## self.aboutdialog.set_website('http://geda.seul.org')
+## self.aboutdialog.set_translator_credits('translator-credits')
+## self.aboutdialog.set_transient_for(self.window)
+
+
+## ####################################
+## # Methods
+## ####################################
+
+## def set_menu_defaults(self):
+## """
+## Method to coordiante which methods should be called to handle
+## the sensitivity of the menu items.
+## """
+## # Project
+## if self.project.name == None or self.project.name == self.no_project_name:
+## self.set_no_project_default()
+## else:
+## self.set_project_default()
+
+
+## def set_no_project_default(self):
+## """
+## Method to set the default sensitivity when no project is loaded.
+## """
+## # File Menu
+## self.project.name = self.no_project_name
+## self.sources_tree.set_property('headers-visible', True)
+## column = self.sources_tree.get_column(0)
+## column.set_title(self.project.name)
+## save_project_as_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Save Project As...')
+## close_project_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+## close_project_menuitem.set_sensitive(False)
+
+
+## def set_project_default(self):
+## """
+## Method to set the default sensitivity when a project is loaded.
+## """
+## # File Menu
+## self.sources_tree.set_property('headers-visible', False)
+## save_project_as_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Save Project As...')
+## close_project_menuitem = self.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+## close_project_menuitem.set_sensitive(True)
+
+
+## def set_project(self, path):
+## """!
+## Method to set current project to the one on path.
+## @param path path for project to open.
+## """
+## # Save current project
+## if not self.project.clean:
+## self.project.save()
+## self.project.open(path)
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project set to ' + self.project.name + '\n')
+## self.dependencyloop.switch_projects()
+
+
+## def set_sources_tree_to_project(self):
+## """ Method to set the tree to current project object. """
+## self.sources.clear()
+## if self.project.name != None:
+## self.load_sources_tree()
+## self.sources_tree.expand_all()
+
+
+## def set_dependencies_tree_to_project(self):
+## """ Method to set the tree to current project object. """
+## self.dependencies.clear()
+## if self.project.dependency_list != None:
+## self.load_dependencies_tree()
+## self.dependencies_tree.expand_all()
+
+
+## def set_dependencies_tree_to_new_project(self):
+## """ Method to set the tree to newly created project object. """
+## #self.dependencyloop.switch_projects()
+## self.dependencies.clear()
+## # Parent Folder
+## project_path = self.project.directory + '/' + self.project.name
+## project_file_path = project_path + '.gm'
+## output_file_path = self.project.directory + '/output.log'
+## error_file_path = self.project.directory + '/error.log'
+
+
+## def load_sources_tree(self):
+## """
+## Method to the load the 'Sources' TreeView from the
+## directory structure of the project.
+## """
+## if self.sources != None:
+## # Clear out the sources first
+## self.sources.clear()
+## # Start adding data to the Model
+## if isinstance(self.project.directory, str):
+## if os.path.exists(self.project.directory):
+## os.chdir(self.project.directory)
+## node = None
+## dictionary = {}
+## icon = gtk.IconTheme() # The icon used throughout the function
+## for root, dirs, files in os.walk(self.project.directory):
+## if root == self.project.directory:
+## image = icon.load_icon(self.utils.icon_lut['project'], 22, 0)
+## else:
+## image = icon.load_icon(self.utils.icon_lut['folder'], 22, 0)
+
+## folder = root.split('/')[-1]
+## try:
+## node = self.sources.append(dictionary[root], [image, folder, root])
+## except KeyError:
+## node = self.sources.append(None, [image, folder, root])
+## for f in [name for dec,name in sorted((os.path.splitext(f)[1][1:],f) for f in files)]: # List expression sorts by file extension
+## if not f.endswith(('~','-','#')):
+## image = icon.load_icon(self.utils.load_image(f), 22, 0)
+## self.sources.append(node, [image, f, os.path.join(root, f)])
+## for d in dirs:
+## dictionary[os.path.join(root, d)] = node
+
+## self.sources_tree.expand_all()
+
+
+## def load_dependencies_tree(self):
+## """!
+## Method to the load the dependencies tree
+## """
+## # Need to add checking for whether or not the filesystem still
+## # has the files before appending them to self.dependencies
+
+## # Either this or have a function that I call before this one that
+## # straightens it all out by going over the dependency_list and making
+## # sure that these files are the correct ones and if not it can call
+## # the functions remove/add/update_dependency() functions
+## def recurse_dependencies(dep_list, parent):
+## for value in dep_list:
+## filename = self.utils.get_filename_from_filepath(value)
+## n_parent = self.dependenices.append(parent, [filename, value])
+## # recurse
+## if self.project.dependency_list[value] != []:
+## recurse_dependencies(self.project.dependency_list[value], n_parent)
+
+## if self.dependencies != None:
+## self.dependencies.clear()
+## for key, value in self.project.dependency_list.iteritems():
+## filename = self.utils.get_filename_from_filepath(key)
+## n_parent = self.dependencies.append(None, [filename, key])
+## # recurse
+## if self.project.dependency_list[key] != []:
+## recurse_dependencies(value, n_parent)
+
+
+## def update_dependency(self, pathname, recurse=False):
+## # First, make sure that the file is already in the dependencies
+## if self.project.dependency_status != None:
+## try:
+## if not recurse:
+## self.project.dependency_status[pathname] = True
+## else:
+## self.project.dependency_status[pathname] = False
+## # recurse over the dependency_list
+## if self.project.dependency_list != None:
+## for value in self.project.dependency_list[pathname]:
+## self.update_dependency(value, True)
+## except KeyError:
+## print 'KeyError_update'
+## finally:
+## self.project.save()
+## self.load_dependencies_tree()
+
+
+## def add_dependency(self, pathname):
+## print 'in add_dependency'
+## try:
+## if self.project.dependency_list != None:
+## self.project.dependency_list[pathname] = []
+## if self.project.dependency_status != None:
+## self.project.dependency_status[pathname] = True
+## except KeyError:
+## print 'KeyError_add'
+## finally:
+## self.project.save()
+## self.load_dependencies_tree()
+
+
+## def remove_dependency(self, pathname, recurse=False):
+## # First, make sure that the file is already in the dependencies
+## if self.project.dependency_status != None:
+## if pathname in self.project.dependency_status:
+## try:
+## # iterate over the dependencies and flatten
+## for value in self.project.dependency_list[pathname]:
+## self.remove_dependency(value, True)
+## self.project.dependency_list[pathname] = []
+## except KeyError:
+## print 'KeyError_remove'
+## finally:
+## if not recurse:
+## del self.project.dependency_status[pathname]
+## del self.project.dependency_list[pathname]
+## else:
+## self.project.dependency_status[pathname] = False
+## self.project.save()
+## self.load_dependencies_tree()
+
+
+## def save_settings(self):
+## """ Method to save current settings to .gmrc file. """
+
+## if self.project.directory and self.project.name:
+## self.settings.project = self.project.directory + '/' + self.project.name + '.gm'
+## else:
+## self.settings.project = None
+## self.settings.create_config_file()
+
+
+## def get_processes_selected_node(self):
+## """!
+## Method to get the selected node in the 'Processes' treeview.
+## @return path of the selected node
+## """
+## selection = self.processes_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## return self.processes.get_value(selection_iter, 2)
+## else:
+## return None
+
+
+## def file_filters(self, dialog):
+## """!
+## Method to abstract some redundant code that is used in the message
+## dialog boxes.
+## @param dialog gtk.FileChooserDialog object
+## """
+## # These are subject to change depending on users input
+## # TODO -- see if we need these at all
+## # also see if we can add multiple filters per name e.g. .vhd and .vhdl
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("All files")
+## file_filter.add_pattern('*')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("schematics (.sch)")
+## file_filter.add_pattern('*.sch')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("symbols (.sym)")
+## file_filter.add_pattern('*.sym')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("pcb (.pcb)")
+## file_filter.add_pattern('*.pcb')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("verilog (.v)")
+## file_filter.add_pattern('*.v')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("vhdl (.vhd)")
+## file_filter.add_pattern('*.vhd')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("bom (.bom)")
+## file_filter.add_pattern('*.bom')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("drc (.drc)")
+## file_filter.add_pattern('*.drc')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("gerber (.gbr)")
+## file_filter.add_pattern('*.gbr')
+## dialog.add_filter(file_filter)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("spice (.spice)")
+## file_filter.add_pattern('*.spice')
+## dialog.add_filter(file_filter)
+
+
+## @exceptions
+## def write_logs(self):
+## """
+## Method to write out the error and output logs with what is in
+## the textbuffers.
+## """
+## startiter, enditer = self.output_textbuffer.get_bounds()
+## output = self.output_textbuffer.get_text(startiter, enditer)
+## os.chdir(self.project.directory)
+## f = file('output.log', 'a')
+## f.writelines(output)
+## f.close()
+
+## startiter, enditer = self.errors_textbuffer.get_bounds()
+## errors = self.errors_textbuffer.get_text(startiter, enditer)
+## os.chdir(self.project.directory)
+## f = file('error.log', 'a')
+## f.writelines(errors)
+## f.close()
+
+
+## @exceptions
+## def kill_processes(self):
+## """
+## Method to kill all the open processes if there are still any
+## open when the gEDAManager is closed.
+## """
+## # TODO - if open processes's prompt the user to save work
+## # before exiting
+## # e.g.
+## # "You have open processes. If you exit you may lose unsaved
+## # changes. Would you like to proceed? Okay or Cancel.
+## for tool, value in self.tools.iteritems():
+## if value != None and not isinstance(value, str): # kill the process
+## os.kill(value.pid, signal.SIGKILL)
+
+
+## ######################################################
+## # Callback Methods -- signal handlers are event driven
+## ######################################################
+
+## def cb_show_about_dialog(self, menuitem, data=None):
+## """!
+## Event handler for About menu button.
+## @param menuitem about menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## self.aboutdialog.show()
+## self.aboutdialog.run()
+## self.aboutdialog.hide()
+
+
+## def cb_url_geda_wiki(self, menuitem, data=None):
+## """!
+## Event handler for gEDA Wiki.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## gnomevfs.url_show('http://geda.seul.org/wiki/')
+
+
+## def cb_url_geda_documentation(self, menuitem, data=None):
+## """!
+## Event handler for gEDA Documentation.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## gnomevfs.url_show('http://geda.seul.org/wiki/geda:documentation')
+
+
+## def cb_url_geda_manager_blog(self, menuitem, data=None):
+## """!
+## Event handler for gEDA Manager.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## gnomevfs.url_show('http://www.gempillar.com')
+
+
+## def cb_url_geda_manager_api_documentation(self, menuitem, data=None):
+## """!
+## Event handler for gEDA Manager.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## gnomevfs.url_show('http://www.gempillar.com/docs/geda-manager')
+
+
+## def cb_new_project(self, menuitem, data=None):
+## """!
+## Event handler for 'New Project'.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## self.project.save()
+## NewProject(self)
+
+
+## def cb_open_project(self, menuitem, data=None):
+## """!
+## Event handler for 'Open Project'.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## self.project.save()
+## dialog = gtk.FileChooserDialog('Open...',
+## self.window,
+## gtk.FILE_CHOOSER_ACTION_OPEN,
+## (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+## gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+
+## dialog.set_default_response(gtk.RESPONSE_OK)
+
+## file_filter = gtk.FileFilter()
+## file_filter.set_name("Project files (*.gm)")
+## file_filter.add_pattern('*.gm')
+## dialog.add_filter(file_filter)
+
+## response = dialog.run()
+## if response == gtk.RESPONSE_OK:
+## self.set_project(dialog.get_filename())
+## dialog.destroy()
+
+
+## def cb_close_project(self, menuitem, data=None):
+## """!
+## Event handler for 'Close Project'.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## self.write_logs()
+## self.project.save()
+## self.project.close()
+## # clear the processes window
+## self.processes.clear()
+
+
+## def cb_project_closed(self, widget, event):
+## """!
+## Event occurs when a Project object is closed
+## @param widget widget that threw the event
+## @param event event that was thrown
+## """
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project closed.\n')
+## self.set_menu_defaults()
+## self.set_sources_tree_to_project()
+## self.set_dependencies_tree_to_project()
+
+
+## def cb_project_saved(self, widget, event):
+## """!
+## Event occurs when a Project object is saved.
+## @param widget widget that threw the event
+## @param event event that was thrown
+## """
+## if self.project.name != None:
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project ' + self.project.name + ' saved.\n')
+## else:
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project saved.\n')
+## self.set_menu_defaults()
+
+
+## def cb_project_opened(self, widget, event):
+## """!
+## Event occurs when a Project object is opened
+## @param widget widget that threw the event
+## @param event event that was thrown
+## """
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\n' + 'Project ' + self.project.name + ' opened.\n')
+## self.set_menu_defaults()
+## self.set_sources_tree_to_project()
+## self.set_dependencies_tree_to_project()
+
+
+## def cb_project_created(self, widget, event):
+## """!
+## Event occurs when a Project object is created
+## @param widget widget that threw the event
+## @param event event that was thrown
+## """
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nProject ' + self.project.name + ' created.\n')
+## self.set_menu_defaults()
+## self.set_sources_tree_to_project()
+## self.set_dependencies_tree_to_new_project()
+
+
+## @exceptions
+## def cb_preferences(self, menuitem, data=None):
+## """!
+## Event occurs when the user opens up the preferences menu.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## def new_source_cursor_changed(newsources_tree):
+## selection = newsources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## self.newsource = model.get_value(selection_iter, 1)
+
+## if self.settings.editor != None:
+## old_editor = self.settings.editor
+## else:
+## old_editor = None
+
+## def response_to_dialog(entry, dialog, response):
+## dialog.response(response)
+
+## entry = gtk.Entry()
+## if self.settings.editor != None:
+## entry.set_text(self.settings.editor)
+## entry.show()
+
+## def cb_filebutton_selection_changed(filechooser, entry):
+## self.settings.editor = filebutton.get_filename()
+## entry.delete_text(0,-1)
+## entry.set_text(self.settings.editor)
+
+## dialog = gtk.MessageDialog(self.window,
+## (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+## gtk.MESSAGE_OTHER,
+## gtk.BUTTONS_OK_CANCEL,
+## gtk.STOCK_DIRECTORY)
+## dialog.set_markup('<b>Preference settings:</b>')
+## dialog.set_title('Preferences')
+## hbox = gtk.HBox()
+## hbox.show()
+
+## filebutton = gtk.FileChooserButton('Text Editor')
+## filebutton.show()
+## filebutton.connect('selection-changed',
+## cb_filebutton_selection_changed, entry)
+## filebutton.set_local_only(True)
+## filebutton.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
+## hbox.pack_end(filebutton)
+
+## entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+## hbox.pack_end(entry)
+## label = gtk.Label('Text Editor:')
+## label.show()
+## hbox.pack_end(label)
+
+## dialog.vbox.pack_end(hbox, True, True, 0)
+## dialog.show()
+## dialog.run()
+## if old_editor != self.settings.editor: # A change was made
+## new_text = self.settings.editor
+## else:
+## new_text = entry.get_text()
+## dialog.destroy()
+
+## if new_text:
+## self.settings.editor = new_text
+
+
+## @exceptions
+## def cb_new_source(self, menuitem, data=None):
+## """!
+## Event occurs when the user wants to add a source to the project
+## @param menuitem menutiem that threw the event
+## @param data optional user data to pass in
+## """
+## def new_source_cursor_changed(newsources_tree):
+## selection = newsources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## self.newsource = model.get_value(selection_iter, 1)
+## else:
+## self.newsource = None
+
+## def response_to_dialog(entry, dialog, response):
+## dialog.response(response)
+
+
+## dialog = gtk.MessageDialog(self.window,
+## (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+## gtk.MESSAGE_QUESTION,
+## gtk.BUTTONS_OK_CANCEL,
+## gtk.STOCK_DIRECTORY)
+## dialog.set_markup('<b>Please enter the new file name (extension will be added):</b>')#\n(add extension to override defaults):</b>')
+## entry = gtk.Entry()
+## entry.show()
+## entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+## hbox = gtk.HBox()
+## hbox.show()
+## hbox.pack_end(entry)
+## label = gtk.Label('File name:')
+## label.show()
+## hbox.pack_end(label)
+
+## # Models for the Tree View
+## newsources = gtk.TreeStore(gtk.gdk.Pixbuf, str)
+## # Tree View
+## newsources_tree = gtk.TreeView(newsources)
+## newsources_tree.show()
+## newsources_tree.connect('cursor-changed', new_source_cursor_changed)
+## # column headings
+## newsources_pixbuf = gtk.CellRendererPixbuf()
+## newsources_pixbuf.set_property('xalign', 0)
+## column = gtk.TreeViewColumn(None, newsources_pixbuf, pixbuf=0)
+## newsources_tree.append_column(column)
+## newsources_cell = gtk.CellRendererText()
+## column = gtk.TreeViewColumn('Source Type', newsources_cell, text=1)
+## column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+## newsources_tree.append_column(column)
+## # populate the tree view
+## icon = gtk.IconTheme()
+## image = icon.load_icon(self.utils.icon_lut['pcb'], 22, 0)
+## newsources.append(None, [image, 'PCB (.pcb)'])
+## image = icon.load_icon(self.utils.icon_lut['sch'], 22, 0)
+## newsources.append(None, [image, 'Schematic (.sch)'])
+## image = icon.load_icon(self.utils.icon_lut['v'], 22, 0)
+## newsources.append(None, [image, 'Verilog (.v)'])
+## image = icon.load_icon(self.utils.icon_lut['vhd'], 22, 0)
+## newsources.append(None, [image, 'VHDL (.vhd)'])
+## image = icon.load_icon(self.utils.icon_lut['sym'], 22, 0)
+## newsources.append(None, [image, 'Symbol (.sym)'])
+
+## # add to the hbox
+## hbox.pack_start(newsources_tree, False, False)
+## dialog.vbox.pack_end(hbox, True, True, 0)
+
+## dialog.show()
+## dialog.run()
+## new_text = entry.get_text()
+## dialog.destroy()
+
+## if new_text and self.newsource != None:
+## # Get the selected_node for the folder to add to
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## selected_node = self.sources.get_value(selection_iter, 2)
+## # Get the type of extension for the program to call
+## if '.' in new_text: # user may have overriden extension
+## return
+## else: # Need to find out what extension from the highlighted node
+## ext = self.newsource[self.newsource.find('.')+1:self.newsource.find(')')]
+## # Make sure a file with the same name doesn't already exist
+## filepath = selected_node + '/' + new_text + '.' + ext
+## filename = new_text + '.' + ext
+## self.utils.update_file_list(self, 1, filepath)
+## self.utils.run_command(self, filepath, None, ext)
+## else:
+## dialog = gtk.MessageDialog(self.window,
+## (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+## gtk.MESSAGE_INFO,
+## gtk.BUTTONS_OK,
+## gtk.STOCK_DIRECTORY)
+## dialog.set_markup('<b>Please enter text and/or make sure a file type is selected.</b>')
+## dialog.show()
+## response = dialog.run()
+## dialog.destroy()
+
+
+## @exceptions
+## def cb_add_copy_source(self, menuitem, data=None):
+## """!
+## Event occurs when the user wants to add a source to the project
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## dialog = gtk.FileChooserDialog('Copy Existing Source To Project...',
+## self.window,
+## gtk.FILE_CHOOSER_ACTION_OPEN,
+## (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+## gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+
+## dialog.set_default_response(gtk.RESPONSE_OK)
+## self.file_filters(dialog)
+## response = dialog.run()
+## if response == gtk.RESPONSE_OK:
+## filepath = dialog.get_filename()
+## self.utils.update_file_list(self, 0, filepath)
+## dialog.destroy()
+
+
+## @exceptions
+## def cb_new_folder(self, action):
+## """!
+## Event occurs when the user chooses to add a new folder to the project.
+## @param action gtk.Action object
+## """
+## def response_to_dialog(entry, dialog, response):
+## dialog.response(response)
+
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## selected_node = self.sources.get_value(selection_iter, 2)
+## if '.' in selected_node:
+## # This is not a folder
+## # YES, this is a hack and was put in place because
+## # we get some problems if the use right clicks on a node before
+## # it becomes highlighted.
+## return
+## os.chdir(selected_node)
+## dialog = gtk.MessageDialog(self.window,
+## (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+## gtk.MESSAGE_QUESTION,
+## gtk.BUTTONS_OK_CANCEL,
+## gtk.STOCK_DIRECTORY)
+## dialog.set_markup('<b>Please enter new folder name:</b>\nIf the folder name you choose exists\non disk in this directory it will deleted.')
+## entry = gtk.Entry()
+## entry.show()
+## entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+## hbox = gtk.HBox()
+## hbox.show()
+## hbox.pack_end(entry)
+## dialog.vbox.pack_end(hbox, True, True, 0)
+## dialog.show()
+## response = dialog.run()
+## text = entry.get_text()
+## if response == gtk.RESPONSE_OK and text.strip() != '':
+## filepath = selected_node + '/' + text
+
+## def delete_dependency_list_entry(arg, dirname, filenames):
+## """ function to delete the filenames from the dependency_list """
+## for f in filenames:
+## print 'looking to delete dependency'
+## if f in self.project.dependency_list and list(self.utils.flatten(self.project.file_list)).count(f) == 1:
+## print 'deleting dependency'
+## del self.project.dependency_list[f]
+
+## # See if this directory already exists
+## if os.path.exists(filepath): # delete directory recursively
+## os.path.walk(filepath, delete_dependency_list_entry, None)
+## shutil.rmtree(filepath)
+## flag = True
+## i = 0
+## while flag:
+## child_iter = self.sources.iter_nth_child(selection_iter, i)
+## if child_iter != None:
+## child_node = self.sources.get_value(child_iter, 2)
+## if child_node == filepath:
+## flag = self.sources.remove(child_iter)
+## if flag: # break out if flag is true
+## flag = False
+## else:
+## break
+## i = i + 1
+## os.mkdir(filepath)
+## dialog.destroy()
+
+
+## @exceptions
+## def cb_delete(self, menuitem, data=None):
+## """!
+## Event handler for 'Delete'. This method will delete the file from the
+## filesystem.
+## @param menuitem that threw the event.
+## @param data optional to pass in.
+## """
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## selected_node = self.sources.get_value(selection_iter, 2)
+## os.system('rm ' + selected_node)
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nDeleted ' + selected_node + '.\n')
+
+
+## @exceptions
+## def cb_delete_folder(self, widget):
+## """!
+## Event occurs when the user chooses to delete a folder from the project.
+## This method will delete the folder from the filesystem.
+## @param widget that threw the event.
+## """
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## selected_node = self.sources.get_value(selection_iter, 2)
+## exists = os.path.exists(selected_node)
+## if exists: # delete directory recursively
+## os.system('rm -rf ' + selected_node)
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nDeleted ' + selected_node + '.\n')
+
+
+## @exceptions
+## def cb_open_in_editor(self, action):
+## """!
+## Event occurs when the user wants to open a source file in the editor.
+## @param action gtk.Action object involved with this event
+## """
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## selected_node = self.sources.get_value(selection_iter, 2)
+## # Run the command as if the file is a text file
+## self.utils.run_command(self, selected_node, None, 'txt')
+
+
+## @exceptions
+## def cb_rename_folder(self, action):
+## """!
+## Event handler for renaming a folder.
+## @param action gtk.Action object involved with this event
+## """
+## def response_to_dialog(entry, dialog, response):
+## dialog.response(response)
+
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## old_path = self.sources.get_value(selection_iter, 2)
+## path = self.sources.get_path(selection_iter)
+
+## dialog = gtk.MessageDialog(self.window,
+## (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+## gtk.MESSAGE_QUESTION,
+## gtk.BUTTONS_OK_CANCEL,
+## gtk.STOCK_DIRECTORY)
+## dialog.set_markup('<b>Please enter the new folder name:\n</b>')
+## entry = gtk.Entry()
+## entry.show()
+## entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+## hbox = gtk.HBox()
+## hbox.show()
+## hbox.pack_end(entry)
+## dialog.vbox.pack_end(hbox, True, True, 0)
+## dialog.show()
+## dialog.run()
+## new_text = entry.get_text()
+## dialog.destroy()
+## new_path = old_path.rpartition('/')[0] + '/' + new_text
+
+## if '.' not in new_text:
+## ## We are going to handle the project folder in cb_rename_folder
+## if old_path == self.project.directory:
+## # Project Folder
+## os.rename(old_path, new_path)
+## project_file = new_path + '/' + self.project.name + '.gm'
+## os.remove(project_file)
+## self.project.directory = new_path
+## self.project.name = new_text
+## ## self.project.file_list[0] = new_text
+## ## self.project.file_list[1][0] = new_text + '.gm'
+## self.project.save()
+## self.output_textbuffer.insert(self.output_textiter, 'Project changed from ' + old_path + ' to ' + new_path + '.\n')
+## else:
+## # Regular folder
+## if os.path.exists(new_path):
+## self.output_textbuffer.insert(self.output_textiter, 'Folder already exists with this name. Cannot rename.\n')
+## return
+## os.rename(old_path, new_path)
+
+
+## @exceptions
+## def cb_rename(self, action):
+## """!
+## Event handler for renaming a file.
+## @param action gtk.Action object involved with this event
+## """
+## def response_to_dialog(entry, dialog, response):
+## dialog.response(response)
+
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## old_path = self.sources.get_value(selection_iter, 2)
+## path = self.sources.get_path(selection_iter)
+
+## dialog = gtk.MessageDialog(self.window,
+## (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+## gtk.MESSAGE_QUESTION,
+## gtk.BUTTONS_OK_CANCEL,
+## gtk.STOCK_DIRECTORY)
+## dialog.set_markup('<b>Please enter the new name\n(including extension if applicable):</b>')
+## entry = gtk.Entry()
+## entry.show()
+## entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+## hbox = gtk.HBox()
+## hbox.show()
+## hbox.pack_end(entry)
+## dialog.vbox.pack_end(hbox, True, True, 0)
+## dialog.show()
+## dialog.run()
+## new_text = entry.get_text()
+## dialog.destroy()
+## new_path = old_path.rpartition('/')[0] + '/' + new_text
+
+## if '.' in new_text and '.' in old_path:
+## # File
+## os.rename(old_path, new_path)
+## self.output_textbuffer.insert(self.output_textiter, old_path + ' changed to ' + new_path + '.\n')
+## elif not '.' in new_text and not '.' in old_path:
+## # Folder -- so image does not need to be changed
+## if os.path.exists(new_path):
+## self.output_textbuffer.insert(self.output_textiter, 'Folder already exists with this name. Cannot rename.\n')
+## return
+## os.rename(old_path, new_path)
+## self.output_textbuffer.insert(self.output_textiter, old_path + ' changed to ' + new_path + '.\n')
+
+
+## @exceptions
+## def cb_cursor_changed(self, widget):
+## """!
+## Event occurs when the cursor changes in the treeview.
+## @param widget widget that threw the event
+## """
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## selected_node = self.sources.get_value(selection_iter, 2)
+## filename = self.utils.get_filename_from_filepath(selected_node)
+## if '.' in filename and not filename.endswith(('.gm','.log')):
+## # Logic to call function to find what type of file it is
+## # and then to populate the according tree view
+## ext = filename.split('.')[-1]
+## self.utils.get_processes_tree(self, selected_node, ext, None, True)
+## # Update 'Processes: ' for the 'Processes' tree
+## column = self.processes_tree.get_column(0)
+## column.set_title('Processes for: ' + filename)
+## column = self.processes_tree.get_column(2)
+## column.set_title('status')
+## else: # We have the project folder
+## # Clear out the columns
+## column = self.processes_tree.get_column(0)
+## column.set_title('')
+## column = self.processes_tree.get_column(2)
+## column.set_title('')
+## # clear out the processes
+## self.processes.clear()
+
+
+## def cb_row_changed(self, model, path, iter):
+## """!
+## Event occurs when the columns change in the dependencies treeview.
+## @param model gtk.TreeStore model for the dependencies
+## """
+## print 'starting cb_row_changed'
+## # We only want a file to appear once
+## def recurse_model(row_iter, row):
+## try:
+## for new_row in row_iter:
+## if new_row[1] not in files:
+## # new_dep_list[new_row[1]] = []
+## new_dep_list[row[1]].append(new_row[1])
+## files.append(new_row[1])
+## new_row_iter = new_row.iterchildren()
+## if new_row_iter != None:
+## recurse_model(new_row_iter, new_row)
+## except StopIteration:
+## print 'StopIteraion'
+## except:
+## print 'except:', sys.exc_info()[0]
+
+## files = []
+## new_dep_list = {}
+## for row in model:
+## if row[1] not in files:
+## new_dep_list[row[1]] = []
+## files.append(row[1])
+## row_iter = row.iterchildren()
+## if row_iter != None:
+## recurse_model(row_iter, row)
+
+
+## print 'files:',files
+## print 'new_dep_list:',new_dep_list
+## self.project.dependency_list = new_dep_list
+
+
+## @exceptions
+## def cb_switch_page(self, notebook, page, page_num):
+## if page_num == 1: # Dependencies notebook tab
+## selection = self.sources_tree.get_selection()
+## selection.unselect_all()
+## self.processes.clear()
+## column = self.processes_tree.get_column(0)
+## column.set_title('')
+## column = self.processes_tree.get_column(2)
+## column.set_title('')
+
+
+## @exceptions
+## def cb_popup_deactivate(self, popup_menu, merge_id):
+## """!
+## Event occurs when the 'deactivate' signal is thrown from
+## the popup menu.
+## @param popup_menu is the popup_menu.
+## @param merge_id is the merge id from the popup uimanager.
+## """
+## # Remove the ui from the uimanager
+## self.popup_uimanager.remove_ui(merge_id)
+
+
+## @exceptions
+## def cb_button_press(self, widget, event):
+## """!
+## This signal handler will be called when the treeview emits
+## a 'button_press_event' signal.
+## @param widget widget that threw the event
+## @param event event that was thrown
+## """
+## if event.button == 3:
+## selection = self.sources_tree.get_selection()
+## model, selection_iter = selection.get_selected()
+## if isinstance(selection_iter, gtk.TreeIter):
+## selected_node = self.sources.get_value(selection_iter, 2)
+## else:
+## return
+## popup_menu = gtk.Menu()
+## actiongroup = gtk.ActionGroup('Popup')
+## actiongroup_list = [('Rename', None, '_Rename', None, None, self.cb_rename),
+## ('Rename Folder', None, '_Rename Folder', None, None, self.cb_rename_folder),
+## ('Open in Editor', None, '_Open in Editor', None, None, self.cb_open_in_editor),
+## ('New Source...', gtk.STOCK_FILE, '_New Source...', None, None, self.cb_new_source),
+## ('Copy Existing Source To Project...', gtk.STOCK_COPY, '_Copy Existing Source To Project...', None, None, self.cb_add_copy_source),
+## ('New Folder', gtk.STOCK_DIRECTORY, 'New _Folder', None, None, self.cb_new_folder),
+## ('Delete', gtk.STOCK_DELETE, '_Delete', '<Control>d', None, self.cb_delete),
+## ('Delete Folder', gtk.STOCK_DELETE, '_Delete Folder', None, None, self.cb_delete_folder),]
+
+
+## actiongroup.add_actions(actiongroup_list)
+## self.popup_uimanager.insert_action_group(actiongroup, 0)
+
+## # Choose Popup Menu
+## if selected_node == self.project.directory:
+## # Project Folder
+## merge_id = self.popup_uimanager.add_ui_from_file(self.utils.directory + '/project_popup.xml')
+## popup_menu = self.popup_uimanager.get_widget('/popup')
+## elif '.' not in selected_node:
+## # Folder
+## merge_id = self.popup_uimanager.add_ui_from_file(self.utils.directory + '/folder_popup.xml')
+## popup_menu = self.popup_uimanager.get_widget('/popup')
+## else:
+## # File
+## if selected_node.endswith('.gm'):
+## return
+## merge_id = self.popup_uimanager.add_ui_from_file(self.utils.directory + '/file_popup.xml')
+## popup_menu = self.popup_uimanager.get_widget('/popup')
+
+## popup_menu.connect('deactivate', self.cb_popup_deactivate, merge_id)
+## popup_menu.show()
+## popup_menu.popup(None, None, None, event.button, event.time)
+
+
+## ## TODO -- combine the next three callbacks in some fashion
+## def cb_exit(self, menuitem, data=None):
+## """!
+## Event handler for 'Exit'.
+## @param menuitem menuitem that threw the event
+## @param data optional user data to pass in
+## """
+## self.dependencyloop.kill_thread()
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nExiting gEDA Manager.\n')
+## self.write_logs()
+## self.dependencies.emit('row-changed', None, None)
+## self.project.save()
+## self.save_settings()
+## self.kill_processes()
+## gtk.main_quit()
+
+
+## def cb_vte(self):
+## """
+## Event handler for when the embedded terminal is exited.
+## """
+## self.dependencyloop.kill_thread()
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nExiting gEDA Manager.\n')
+## self.write_logs()
+## self.dependencies.emit('row-changed', None, None)
+## self.project.save()
+## self.save_settings()
+## self.kill_processes()
+## gtk.main_quit()
+
+
+## def cb_destroy(self, event):
+## """!
+## Event handlder when the form is closed in any fashion.
+## @param event event that was thrown
+## """
+## self.dependencyloop.kill_thread()
+## self.output_textbuffer.insert(self.output_textiter, self.utils.get_time() + ':\nExiting gEDA Manager.\n')
+## self.write_logs()
+## self.dependencies.emit('row-changed', None, None)
+## self.project.save()
+## self.save_settings()
+## self.kill_processes()
+## gtk.main_quit()
+
+## ########################################################
+
+## def main(self):
+## """ Method starts the main loop for gtk. """
+## gtk.main()
+
+
+## if __name__ == "__main__":
+## geda_manager = gEDAManager()
+## geda_manager.main()
+
+
diff --git a/src/gui/temp.py.~1~ b/src/gui/temp.py.~1~
new file mode 100644
index 0000000..8d1c8b6
--- /dev/null
+++ b/src/gui/temp.py.~1~
@@ -0,0 +1 @@
+
diff --git a/src/gui/xml/file_popup.xml b/src/gui/xml/file_popup.xml
new file mode 100644
index 0000000..8ddac06
--- /dev/null
+++ b/src/gui/xml/file_popup.xml
@@ -0,0 +1,9 @@
+<ui>
+ <popup>
+ <separator/>
+ <menuitem action="Open in Editor"/>
+ <menuitem action="Rename"/>
+ <menuitem action="Delete"/>
+ <separator/>
+ </popup>
+</ui>
diff --git a/src/gui/xml/folder_popup.xml b/src/gui/xml/folder_popup.xml
new file mode 100644
index 0000000..7b74efe
--- /dev/null
+++ b/src/gui/xml/folder_popup.xml
@@ -0,0 +1,11 @@
+<ui>
+ <popup>
+ <separator/>
+ <menuitem action="New Source..."/>
+ <menuitem action="New Folder"/>
+ <menuitem action="Delete Folder"/>
+ <menuitem action="Rename Folder"/>
+ <menuitem action="Copy Existing Source To Project..."/>
+ <separator/>
+ </popup>
+</ui>
diff --git a/src/gui/xml/menu.xml b/src/gui/xml/menu.xml
new file mode 100644
index 0000000..9e4e0e5
--- /dev/null
+++ b/src/gui/xml/menu.xml
@@ -0,0 +1,24 @@
+<ui>
+ <menubar name="MenuBar">
+ <menu action="Project">
+ <menuitem action="New Project"/>
+ <menuitem action="Open Project"/>
+ <menuitem action="Close Project"/>
+ <separator/>
+ <menuitem action="Exit"/>
+ </menu>
+ <menu action="Edit">
+ <menuitem action="Preferences..."/>
+ </menu>
+ <menu action="Help">
+ <menu action="Web Resources">
+ <menuitem action="gEDA Wiki"/>
+ <menuitem action="gEDA Documentation"/>
+ <menuitem action="gEDA Manager Documentation"/>
+ <menuitem action="gEDA Manager API Documentation"/>
+ </menu>
+ <separator/>
+ <menuitem action="About"/>
+ </menu>
+ </menubar>
+</ui>
diff --git a/src/gui/xml/project_popup.xml b/src/gui/xml/project_popup.xml
new file mode 100644
index 0000000..ac7b532
--- /dev/null
+++ b/src/gui/xml/project_popup.xml
@@ -0,0 +1,9 @@
+<ui>
+ <popup>
+ <separator/>
+ <menuitem action="New Folder"/>
+ <menuitem action="New Source..."/>
+ <menuitem action="Copy Existing Source To Project..."/>
+ <separator/>
+ </popup>
+</ui>
diff --git a/src/lib/__init__.py b/src/lib/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/lib/decorators.py b/src/lib/decorators.py
deleted file mode 100644
index be858e0..0000000
--- a/src/lib/decorators.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#! /usr/bin/env python
-
-# gEDA Manager
-# Copyright (C) 2008 Newell Jensen
-# Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
-##@package lib.decorators
-#Library file for decorators
-#@author Newell Jensen
-
-import sys, time
-
-
-def exceptions(func):
- """!
- Exceptions decorator for functions that are in the Utils or gEDAManager
- class. Decorator to decorate functions for generic exception handling
- and logging this to the errors text buffer.
- @param func function that will be decorated
- @return func_to_decorate which is the decorated function
- """
- def func_to_decorate(*args):
- """!
- New function that is returned by exceptions decorator.
- @param *args arguments that are passed to the the function that
- is being decorated (func)
- @return decorated function
- """
- f = None
- for arg in args:
- if hasattr(arg, 'errors_textbuffer'):
- try:
- f = func(*args)
- except IOError:
- arg.errors_textbuffer.insert(arg.errors_textiter, time.asctime(time.localtime(time.time())) + ':\nIOError- ' + str(sys.exc_info()) + ' ' + str(func) + '.\n')
- except OSError:
- arg.errors_textbuffer.insert(arg.errors_textiter, time.asctime(time.localtime(time.time())) + ':\nOSError- ' + str(sys.exc_info()) + ' ' + str(func) + '.\n')
- except IndexError:
- arg.errors_textbuffer.insert(arg.errors_textiter, time.asctime(time.localtime(time.time())) + ':\nIndexError- ' + str(sys.exc_info()) + ' ' + str(func) + '.\n')
- except TypeError:
- arg.errors_textbuffer.insert(arg.errors_textiter, time.asctime(time.localtime(time.time())) + ':\nTypeError- ' + str(sys.exc_info()) + ' ' + str(func) + '.\n')
- except:
- arg.errors_textbuffer.insert(arg.errors_textiter, time.asctime(time.localtime(time.time())) + ':\nUnexpected error- ' + str(sys.exc_info()) + ' ' + str(func) + '.\n')
- raise
- return f
-
- return func_to_decorate
diff --git a/src/menu.xml b/src/menu.xml
deleted file mode 100644
index 9e4e0e5..0000000
--- a/src/menu.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<ui>
- <menubar name="MenuBar">
- <menu action="Project">
- <menuitem action="New Project"/>
- <menuitem action="Open Project"/>
- <menuitem action="Close Project"/>
- <separator/>
- <menuitem action="Exit"/>
- </menu>
- <menu action="Edit">
- <menuitem action="Preferences..."/>
- </menu>
- <menu action="Help">
- <menu action="Web Resources">
- <menuitem action="gEDA Wiki"/>
- <menuitem action="gEDA Documentation"/>
- <menuitem action="gEDA Manager Documentation"/>
- <menuitem action="gEDA Manager API Documentation"/>
- </menu>
- <separator/>
- <menuitem action="About"/>
- </menu>
- </menubar>
-</ui>
diff --git a/src/newproject.py b/src/newproject.py
deleted file mode 100644
index 532d0d5..0000000
--- a/src/newproject.py
+++ /dev/null
@@ -1,350 +0,0 @@
-"""
-gEDA Manager
-Copyright (C) 2008 Newell Jensen
-Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-"""
-
-##@package src.newproject
-#New Project window for the gEDA Manager
-#@author Newell Jensen
-
-import os, sys, pygtk, gtk, yaml, shutil
-pygtk.require('2.0')
-from project import *
-
-class NewProject:
- """
- Window for creating a New Project with
- the gEDA Manager. This form is called
- when the user wants to create a new project.
- """
- def __init__(self, gedamanager):
- """!
- NewProject Constructor.
- @param gedamanager gEDAManager object that the new project is
- called from
- """
- self.gedamanager = gedamanager
- self.assistant = gtk.Assistant()
- self.assistant.connect('close', self.cb_close)
- self.assistant.connect('apply', self.cb_apply)
- self.assistant.connect('cancel', self.cb_cancel)
- self.assistant.set_title('gEDA Manager')
- self.assistant.set_size_request(400, 300)
- image = self.assistant.render_icon(gtk.STOCK_NEW, gtk.ICON_SIZE_DIALOG)
-
- ###############################
- # Choose project filename page
- ###############################
-
- vbox = gtk.VBox()
- vbox.set_border_width(12)
- vbox.set_spacing(6)
- vbox.show()
- label = gtk.Label('')
- label.set_markup('<b>Choose project filename</b>')
- label.set_line_wrap(True)
- label.set_alignment(0, 0.5)
- label.show()
- vbox.pack_start(label, False, False)
-
- align = gtk.Alignment(0, 0, 1, 1)
- vbox.pack_start(align, True, True)
- align.set_padding(12, 12, 12, 12)
- align.show()
-
- options = gtk.VBox()
- options.show()
- align.add(options)
-
- table = gtk.Table(2,2)
- table.show()
- table.set_col_spacings(6)
- table.set_row_spacings(6)
- label = gtk.Label('Project name:')
- label.set_alignment(0, 0.5)
- label.show()
- table.attach(label, 0, 1, 0, 1, gtk.FILL, 0)
- self.filename = gtk.Entry()
- self.filename.show()
- table.attach(self.filename, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, 0)
- label = gtk.Label('Location:')
- label.set_alignment(0, 0.5)
- label.show()
- table.attach(label, 0, 1, 1, 2, gtk.FILL, 0)
-
- def cb_filebutton_selection_changed(filechooser):
- """!
- Function to handle when the filebutton selection is changed.
- @param filechooser gtk.FileChooserButton object
- """
- os.chdir(self.get_path())
-
- self.filebutton = gtk.FileChooserButton('Select project location...')
- self.filebutton.show()
- self.filebutton.connect('selection-changed',
- cb_filebutton_selection_changed)
- self.filebutton.set_local_only(True)
- self.filebutton.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
- table.attach(self.filebutton, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND, 0)
- options.pack_start(table, False, False)
-
- self.assistant.append_page(vbox)
- self.assistant.set_page_title(vbox, 'Create a new project')
- self.assistant.set_page_type(vbox, gtk.ASSISTANT_PAGE_CONTENT)
- self.assistant.set_page_side_image(vbox, image)
- self.assistant.set_page_complete(vbox, False)
- self.filename_page = vbox
-
- def cb_filename_changed(filename_entry):
- """!
- Function to handle when the filename is changed.
- @param filename_entry text entered for the file and
- directory to be created
- """
- self.assistant.set_page_complete(self.filename_page,
- (filename_entry != ""))
-
-
- self.filename.connect('changed', cb_filename_changed)
-
- ########################
- # Creation Summary page
- ########################
-
- vbox = gtk.VBox()
- vbox.set_border_width(12)
- vbox.set_spacing(6)
- vbox.show()
- label = gtk.Label('')
- label.set_markup('<b>Project Summary</b>')
- label.set_line_wrap(True)
- label.set_alignment(0, 0.5)
- label.show()
- vbox.pack_start(label, False, False)
-
- align = gtk.Alignment(0, 0, 1, 1)
- vbox.pack_start(align, True, True)
- align.set_padding(12, 12, 12, 12)
- align.show()
-
- explanation = gtk.VBox()
- explanation.show()
- align.add(explanation)
-
- self.new_directory_frame = gtk.Frame('')
- self.new_directory_frame.get_label_widget().set_markup('<b>New file and directory to be created:</b>')
- self.new_directory_frame.set_shadow_type(gtk.SHADOW_NONE)
- explanation.pack_start(self.new_directory_frame, False, False)
-
- align = gtk.Alignment(0, 0, 1, 1)
- align.set_padding(0, 12, 12, 12)
- align.show()
- self.new_directory_frame.add(align)
-
- self.new_directory = gtk.Label()
- self.new_directory.set_alignment(0, 0.5)
- self.new_directory.set_padding(0, 12)
- self.new_directory.show()
- align.add(self.new_directory)
-
- self.overwrite_frame = gtk.Frame('')
- self.overwrite_frame.get_label_widget().set_markup('<b>The following directory would be over written:</b>')
- self.overwrite_frame.set_shadow_type(gtk.SHADOW_NONE)
- self.overwrite_frame.show()
- explanation.pack_start(self.overwrite_frame, False, False)
-
- align = gtk.Alignment(0, 0, 1, 1)
- align.set_padding(0, 12, 12, 12)
- align.show()
- self.overwrite_frame.add(align)
-
- vbox1 = gtk.VBox()
- vbox1.show()
- align.add(vbox1)
-
- self.overwrite_list = gtk.Label()
- self.overwrite_list.set_alignment(0, 0.5)
- self.overwrite_list.set_padding(0, 12)
- self.overwrite_list.show()
- vbox1.pack_start(self.overwrite_list, False, False)
-
- self.confirm_overwrite = gtk.CheckButton('Confirm overwrite')
- self.confirm_overwrite.show()
- vbox1.pack_start(self.confirm_overwrite, False, False)
-
- def cb_confirm_overwrite_toggled(togglebutton):
- """!
- Function is called when there is already a file with the same
- name as the one that is trying to be created.
- @param togglebutton widget that is either checked (activated)
- or not checked (not activated)
- """
- confirmed = togglebutton.get_active()
- self.assistant.set_page_complete(self.summary_page, confirmed)
-
- self.confirm_overwrite.connect('toggled', cb_confirm_overwrite_toggled)
-
- self.assistant.append_page(vbox)
- self.assistant.set_page_title(vbox, 'Create new project')
- self.assistant.set_page_side_image(vbox, image)
- self.assistant.set_page_type(vbox, gtk.ASSISTANT_PAGE_CONFIRM)
- self.assistant.show()
- self.summary_page = vbox
-
- def check_directory_overwrite():
- """!
- Function to check whether or not the directory to be created
- already exists.
- @return list
- """
- filename = self.get_filename().split('.')[0]
- f = os.path.exists(self.get_path() + '/' + filename)
- new_directory = []
- overwrite_list = []
-
- if f:
- overwrite_list.append(filename)
- else:
- new_directory.append(filename)
- return [new_directory, overwrite_list]
-
-
- def cb_prepare(assistant, page):
- """!
- Function to help setup the assistant summary page.
- @param assistant gtk.Assistant object
- @param page one of the pages of the gtk.Assistant object
- """
- if page is self.summary_page:
- # Summary page before creating the new project on disk
- [new_directory, overwrite_list] = check_directory_overwrite()
- self.new_directory.set_text('\n'.join(new_directory))
- self.overwrite_list.set_text('\n'.join(overwrite_list))
-
- no_new_directory = (new_directory == [])
- if no_new_directory:
- self.new_directory_frame.hide_all()
- else:
- self.new_directory_frame.show_all()
-
- no_overwrite = (overwrite_list == [])
- if no_overwrite:
- # No files will be overwritten, we are done
- self.overwrite_frame.hide_all()
- self.assistant.set_page_complete(self.summary_page, True)
- else:
- # Need confirmation before overwriting files
- self.overwrite_frame.show_all()
- self.confirm_overwrite.set_active(False)
-
- self.assistant.connect('prepare', cb_prepare)
-
-
- ######################################
- # Callback Methods
- ######################################
-
- def cb_close(self, assistant):
- """!
- Method is called when the NewProject object is closed.
- @param assistant gtk.Assistant object
- """
- self.assistant.destroy()
-
- def cb_cancel(self, assistant):
- """!
- Method is called when the the user chooses 'cancel'.
- @param assistant gtk.Assistant object
- """
- self.assistant.destroy()
-
- def cb_apply(self, assistant):
- """!
- Method is called when the user chooses 'apply' to create
- the new project.
- @param assistant gtk.Assistant object
- """
- try:
- # Set new project attributes
- self.gedamanager.project.name = self.get_filename().split('.')[0]
- self.gedamanager.project.directory = self.get_path() + '/' + self.gedamanager.project.name.split('.')[0]
- self.gedamanager.project.dependency_list = {}
- self.gedamanager.project.dependency_status = {}
- # Remove directories with imported remove_tree
- if self.confirm_overwrite.get_active():
- shutil.rmtree(self.gedamanager.project.directory)
-
- os.mkdir(self.gedamanager.project.directory)
- self.gedamanager.project.create()
- self.gedamanager.dependencyloop.switch_projects()
- except IOError, (errno, strerror):
- md = gtk.MessageDialog(self.assistant,
- (gtk.DIALOG_MODAL |
- gtk.DIALOG_DESTROY_WITH_PARENT),
- gtk.MESSAGE_ERROR,
- gtk.BUTTONS_OK)
-
- md.set_markup('<span weight="bold" size="larger">Could not create project</span>\n\nError %i: %s') % (errno, strerror)
- md.show_all()
- md.run()
- md.hide_all()
- return
- except:
- self.gedamanager.errors_textbuffer.insert(g.errors_textiter, 'Unexpected error: ' + str(sys.exc_info()[0]) + '.\n')
- md = gtk.MessageDialog(self.assistant,
- (gtk.DIALOG_MODAL |
- gtk.DIALOG_DESTROY_WITH_PARENT),
- gtk.MESSAGE_ERROR,
- gtk.BUTTONS_OK)
-
- md.set_markup('<span weight="bold" size="larger">Could not create project</span>')
- md.show_all()
- md.run()
- md.hide_all()
-
-
- ######################################
- # Methods
- ######################################
-
- def get_path(self):
- """!
- Method to get path of new project.
- @return filepath from the filebutton
- """
- filepath = self.filebutton.get_filename()
- return filepath
-
-
- def get_filename(self):
- """!
- Method to get file name of the new project.
- @return filename for the new project file
- """
- filename = self.filename.get_text()
- if not filename.endswith('.gm'):
- filename += '.gm'
- return filename
-
-
- def main(self):
- """ Method starts the main loop for gtk. """
- gtk.main()
-
-
-
diff --git a/src/processdependencyevent.py b/src/processdependencyevent.py
deleted file mode 100644
index 2badf5b..0000000
--- a/src/processdependencyevent.py
+++ /dev/null
@@ -1,113 +0,0 @@
-"""
-gEDA Manager
-Copyright (C) 2008 Newell Jensen
-Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-"""
-
-##@package src.processevent
-#Class to process the events from the thread executed by DependencyLoop
-#@author Newell Jensen
-
-import gtk, pygtk, time
-pygtk.require('2.0')
-from utils import *
-from pyinotify import *
-
-class ProcessDependencyEvent(ProcessEvent):
- """
- Class to process the events from the thread executed by DependencyLoop.
- """
- def __init__(self, gedamanager):
- """!
- Constructor for the ProcessDependencyEvent class.
- @param gedamanager current gEDAManager instance
- """
- self.g = gedamanager
- self.quit = False
-
-
- def cb_main_thread(self, event):
- """!
- Method to call the 'gtk' modifying code in the main thread.
- @param event current event that was caught for the section of
- filesystem under watch
- """
- self.g.load_sources_tree()
- # file extensions that should be ignored
- if not event.pathname.endswith(('-','~','#','.save','.log','.gm')):
- print event.maskname
- print event.pathname
- if event.maskname == 'IN_MODIFY':
- self.g.update_dependency(event.pathname)
- elif event.maskname == 'IN_DELETE':
- self.g.remove_dependency(event.pathname)
- elif event.maskname == 'IN_CREATE':
- self.g.add_dependency(event.pathname)
- elif event.maskname == 'IN_MOVED_FROM':
- self.g.remove_dependency(event.pathname)
- elif event.maskname == 'IN_MOVED_TO':
- self.g.add_dependency(event.pathname)
-
-
- def process_IN_MODIFY(self, event):
- """!
- Method to process the IN_MODIFY event from the pyinotify module.
- @param event current IN_MODIFY event that was caught for the section of
- filesystem under watch
- """
- gobject.idle_add(self.cb_main_thread, event)
-
-
- def process_IN_DELETE(self, event):
- """!
- Method to process the IN_DELETE event from the pyinotify module.
- @param event current IN_DELETE event that was caught for the section of
- filesystem under watch
- """
- gobject.idle_add(self.cb_main_thread, event)
-
-
- def process_IN_CREATE(self, event):
- """!
- Method to process the IN_CREATE event from the pyinotify module.
- @param event current IN_CREATE event that was caught for the section of
- filesystem under watch
- """
- gobject.idle_add(self.cb_main_thread, event)
-
-
- def process_IN_MOVED_FROM(self, event):
- """!
- Method to process the IN_MOVED_FROM event from the pyinotify module.
- @param event current IN_MOVED_FROM event that was caught for the
- section of filesystem under watch
- """
- gobject.idle_add(self.cb_main_thread, event)
-
-
- def process_IN_MOVED_TO(self, event):
- """!
- Method to process the IN_MOVED_FROM event from the pyinotify module.
- @param event current IN_MOVED_FROM event that was caught for the
- section of filesystem under watch
- """
- gobject.idle_add(self.cb_main_thread, event)
-
-
-
-
-
diff --git a/src/project.py b/src/project.py
deleted file mode 100644
index d1810c6..0000000
--- a/src/project.py
+++ /dev/null
@@ -1,150 +0,0 @@
-"""
-gEDA Manager
-Copyright (C) 2008 Newell Jensen
-Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-"""
-
-##@package src.project
-# Project class for the gEDA Manager project objects
-#@author Newell Jensen
-
-import os, sys, yaml, gtk, pygtk, gobject
-pygtk.require('2.0')
-
-
-class Project(gobject.GObject):
- """
- The Project class contains
- -- name (name of the project)
- -- directory (root directory of the project)
- -- dependency_list (dictionary of files and their dependencies)
- -- dependnecy_status (dictionary of files and their updated/outdated status)
- """
- __gsignals__ = {'closed': (gobject.SIGNAL_NO_RECURSE,
- gobject.TYPE_NONE,
- (gobject.TYPE_BOOLEAN, )),
- 'saved': (gobject.SIGNAL_NO_RECURSE,
- gobject.TYPE_NONE,
- (gobject.TYPE_BOOLEAN, )),
- 'opened': (gobject.SIGNAL_NO_RECURSE,
- gobject.TYPE_NONE,
- (gobject.TYPE_BOOLEAN, )),
- 'created': (gobject.SIGNAL_NO_RECURSE,
- gobject.TYPE_NONE,
- (gobject.TYPE_BOOLEAN, )),
- }
-
-
- def __init__(self, filepath=None):
- """ Default Constructor. """
- gobject.GObject.__init__(self)
-
- if filepath != None:
- try:
- self.name = filepath.rsplit('/')[-1].split('.')[0]
- self.directory = filepath.rpartition('/')[0]
- # open up project file
- project = yaml.load(open(filepath))
- except IOError:
- project = 0
- except yaml.YAMLError, exc:
- if hasattr(exc, 'problem_mark'):
- mark = exc.problem_mark
- print 'There is an error in the' + filepath + 'file.\n'
- print "Error position: (%s:%s)" % (mark.line+1, mark.column+1)
- exit(-1)
-
- if project:
- # parse the config object and get list of apps
- stream = file(filepath, 'r')
- for data in yaml.load_all(stream):
- self.dependency_status = data['dependency_status']
- self.dependency_list = data['dependency_list']
- stream.close()
- elif not project:
- self.dependency_status = None
- self.dependency_list = None
- else:
- self.name = None
- self.directory = None
- self.dependency_status = None
- self.dependency_list = None
- self.clean = False
-
-
- def close(self):
- """
- Method to close the current project and then
- emit the 'closed' signal.
- """
- self.name = None
- self.directory = None
- self.dependency_status = None
- self.dependency_list = None
- self.emit('closed', True)
-
-
- def create(self):
- """
- Method to save the project and then emit the
- 'created' signal.
- """
- self.save(True)
- self.emit('created', True)
-
-
- def save(self, silent=None):
- """!
- Method to save the project file and then emit the 'saved' signal if succesful
- @param silent flag for whether or not the 'saved' signal should be emitted
- """
- if self.name != None and self.directory != None:
- filepath = self.directory + '/' + self.name + '.gm'
- try:
- stream = file(filepath, 'w')
- yaml.dump({'project': filepath,
- 'dependency_list': self.dependency_list,
- 'dependency_status': self.dependency_status},
- stream, default_flow_style=False)
- stream.close()
- except IOError:
- print 'IOError:', sys.exc_info()[0]
- self.clean = True
- if not silent:
- self.emit('saved', True)
-
-
- def open(self, filepath):
- """!
- Method to open up project from path and set as current project
- @param filepath filepath of the project file to open
- """
- self.name = filepath.rsplit('/')[-1].split('.')[0]
- self.directory = filepath.rpartition('/')[0]
- try:
- stream = file(filepath, 'r')
- for data in yaml.load_all(stream):
- self.dependency_status = data['dependency_status']
- self.dependency_list = data['dependency_list']
- self.clean = True
- self.emit('opened', True)
- except IOError:
- print 'IOError:', sys.exc_info()[0]
-
-gobject.type_register(Project)
-
-
diff --git a/src/project_popup.xml b/src/project_popup.xml
deleted file mode 100644
index ac7b532..0000000
--- a/src/project_popup.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<ui>
- <popup>
- <separator/>
- <menuitem action="New Folder"/>
- <menuitem action="New Source..."/>
- <menuitem action="Copy Existing Source To Project..."/>
- <separator/>
- </popup>
-</ui>
diff --git a/src/settings.py b/src/settings.py
deleted file mode 100644
index 82723f0..0000000
--- a/src/settings.py
+++ /dev/null
@@ -1,141 +0,0 @@
-"""
-gEDA Manager
-Copyright (C) 2008 Newell Jensen
-Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-"""
-
-##@package src.settings
-#Create and verify settings for the gEDA Manager
-#Create and update the gEDA Manager configuration file .gmrc
-#@author Newell Jensen
-
-import os, sys, gtk, string, signal, yaml
-from subprocess import *
-
-
-class Settings:
- """
- Settings for the gEDA Manager.
- This class takes care of configuring
- the applicaton settings.
- """
- def __init__(self):
- """ Settings Default Constructor. """
- self.version = 0.1
- ## self.installed_apps = []
- self.project = None
- self.editor = None
- self.path = os.path.expanduser('~') + '/.gmrc'
- ## self.geda_apps = ['gschem','pcb','gsch2pcb','gnucap','ngspice',
- ## 'iverilog','gattrib','gtkwave','gwave','gnetlist',
- ## 'tragesym','grenum','gerbv','wcalc','mcalc','olib']
- try:
- config = yaml.load(open(self.path))
- except IOError:
- config = 0
- except yaml.YAMLError, exc:
- if hasattr(exc, 'problem_mark'):
- mark = exc.problem_mark
- print "There is an error in the .gmrc file.\n"
- print "Error position: (%s:%s)" % (mark.line+1, mark.column+1)
- exit(-1)
-
- if config:
- # parse the config object and get list of apps
- stream = file(self.path, 'r')
-
- for data in yaml.load_all(stream):
- ## self.installed_apps = data['programs']
- self.project = data['project']
- self.editor = data['editor']
- # Check to see if this file is still available
- if self.project != None:
- try:
- f = open(self.project)
- except IOError:
- md = gtk.MessageDialog(None,
- (gtk.DIALOG_MODAL |
- gtk.DIALOG_DESTROY_WITH_PARENT),
- gtk.MESSAGE_ERROR,
- gtk.BUTTONS_OK)
- md.set_markup('<span weight="bold" size="larger">Could not open project: ' + self.project + '.</span>')
- error_image = gtk.image_new_from_stock('gtk-dialog-error',
- gtk.ICON_SIZE_DIALOG)
- error_image.show()
- md.set_image(error_image)
- md.show_all
- md.run()
- md.hide_all()
- self.project = None
- stream.close()
- elif not config:
- # find installed apps and create the config file
- ## self.installed_apps = self.find_installed_apps()
- self.create_config_file()
-
-
- ## def find_installed_apps(self):
- ## """!
- ## Find all of the gEDA suite applications that are
- ## installed on this machine and return list of these programs.
- ## @return list of installed geda apps
- ## """
- ## apps = []
- ## for app in self.geda_apps:
- ## # Check to see if program is installed
- ## args = 'which ' + app
- ## path = Popen(['which', app], stdout=PIPE).communicate()[0]
- ## #get name from path
- ## path = path.strip('\n')
- ## geda_app = path.rsplit('/',1)
- ## try:
- ## apps.append(geda_app[1])
- ## except IndexError:
- ## print 'IndexError:', sys.exc_info()[0]
- ## print 'The application ' + app + ' is not installed.'
- ## return apps
-
-
- def create_config_file(self):
- """ Create the configuration file for the gEDA Manager. """
- stream = file(self.path, 'w')
- document = """
- purpose: |
-
- .gmrc is the configuration file for the gEDA Manager.
- It stores the list of geda programs that the user wants to
- include in the manager. This file can be edited so that only
- the programs of interest will be visible to the manager. To
- do this simply edit the list of programs below. However, if
- you edit this file and add a program it is your responsibility
- to make sure that this program is installed on your system.
- If this program is not installed on your system, this will
- cause errors and/or undesirable functionality.
-
- In the case that someone creates a new geda application and would
- like it to be included in the gEDA Manager workflow, you will need
- to update the geda_apps list located in the Settings.__init__
- method in the settings.py file.
-
- """
- yaml.dump(yaml.load(document), stream, default_flow_style=False)
- yaml.dump({'version': self.version,
- 'project': self.project,
- 'editor': self.editor}, stream, default_flow_style=False)
- stream.close()
-
-
diff --git a/src/utils.py b/src/utils.py
deleted file mode 100644
index 541d0d2..0000000
--- a/src/utils.py
+++ /dev/null
@@ -1,667 +0,0 @@
-"""
-gEDA Manager
-Copyright (C) 2008 Newell Jensen
-Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-"""
-
-##@package src.utils
-#Utility class for the gEDA Manager
-#@author Newell Jensen
-
-import os, pygtk, gtk, dbus, time
-pygtk.require('2.0')
-from lib.decorators import exceptions
-from gsch2pcb import Gsch2pcb
-from project import *
-from settings import *
-from subprocess import *
-from stat import *
-from dbus.mainloop.glib import DBusGMainLoop
-
-
-class Utils:
- """
- Utility class for the gEDA Manager.
- """
- def __init__(self):
- """!
- Constructor of the Utils class. Utils is a utility class for the
- gEDAManager class.
- @param gedamanager current gEDAManager instance
- """
- self.directory = os.getcwd()
- self.__setup__()
-
-
- def __setup__(self):
- """ Method to load the icon look up table and netlists list. """
- self.configfiles = ['gschemrc','.gschemrc','gafrc','.gafrc','gnetlistrc','.gnetlistrc','gattribrc','.gattribrc','attribs','.attribs']
-
- self.netlists = ['bom2','calay','mathematica','vipec','geda','systemc','allegro','redac','drc2','cascade','pads','bae','pcbpins','vams','drc','gsch2pcb','partslist2','partslist3','partslist-common','gossip','maxascii','PCB','vhdl','tango','spice-sdb','partstlist1','PCBboard','switchcap','osmond','spice','verilog','bom','eagle','protelII','futurenet2']
-
- # Images to import for later use
- image = gtk.gdk.pixbuf_new_from_file('../images/icons/geda-xgsch2pcb-48.png')
- gtk.icon_theme_add_builtin_icon('gEDAManager', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/gq-folder.png')
- gtk.icon_theme_add_builtin_icon('folder', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/application_home.png')
- gtk.icon_theme_add_builtin_icon('project', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/page.png')
- gtk.icon_theme_add_builtin_icon('gm', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/page_white.png')
- gtk.icon_theme_add_builtin_icon('log', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/verilog-module.bmp')
- gtk.icon_theme_add_builtin_icon('v', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/vhdl-module.bmp')
- gtk.icon_theme_add_builtin_icon('vhd', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/vhdl-module.bmp')
- gtk.icon_theme_add_builtin_icon('vhdl', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/page_white_error.png')
- gtk.icon_theme_add_builtin_icon('other', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/chart_curve.png')
- gtk.icon_theme_add_builtin_icon('spice', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/background-logo-icon.png')
- gtk.icon_theme_add_builtin_icon('icarus', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/GHDL_logo-22.png')
- gtk.icon_theme_add_builtin_icon('ghdl', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/application_xp_terminal.png')
- gtk.icon_theme_add_builtin_icon('terminal', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/tick.png')
- gtk.icon_theme_add_builtin_icon('updated', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/flag_red.png')
- gtk.icon_theme_add_builtin_icon('outdated', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/report.png')
- gtk.icon_theme_add_builtin_icon('output', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/exclamation.png')
- gtk.icon_theme_add_builtin_icon('errors', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/image.png')
- gtk.icon_theme_add_builtin_icon('png', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/gerbv-22.png')
- gtk.icon_theme_add_builtin_icon('gerbv', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/LaTeX.png')
- gtk.icon_theme_add_builtin_icon('tex', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/money.png')
- gtk.icon_theme_add_builtin_icon('bom', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/page_gear.png')
- gtk.icon_theme_add_builtin_icon('config', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/bullet_wrench.png')
- gtk.icon_theme_add_builtin_icon('cmd', 22, image)
- image = gtk.gdk.pixbuf_new_from_file('../images/bitmaps/text_align_center.png')
- gtk.icon_theme_add_builtin_icon('txt', 22, image)
-
-
- self.configfiles = ['gschemrc','.gschemrc','gafrc','.gafrc','gnetlistrc','.gnetlistrc','gattribrc','.gattribrc','attribs','.attribs']
-
- self.icon_lut = {'txt': 'txt',
- 'cmd': 'cmd',
- 'config': 'config',
- 'bom': 'bom',
- 'bom1': 'bom',
- 'bom2': 'bom',
- 'tex': 'tex',
- 'gerbv': 'gerbv',
- 'png': 'png',
- 'errors': 'errors',
- 'output': 'output',
- 'outdated': 'outdated',
- 'updated': 'updated',
- 'terminal': 'terminal',
- 'gattrib': 'geda-gattrib',
- 'gschem': 'geda-gschem',
- 'spice': 'spice',
- 'icarus': 'icarus',
- 'ghdl': 'ghdl',
- 'other': 'other',
- 'vhd': 'vhd',
- 'vhdl': 'vhdl',
- 'v': 'v',
- 'log': 'log',
- 'gm': 'gm',
- 'project': 'project',
- 'folder': 'folder',
- 'terminal': 'terminal',
- 'gEDAManager': 'gEDAManager',
- 'sch': 'application-x-geda-schematic',
- 'sym': 'application-x-geda-symbol',
- 'gsch2pcb': 'application-x-geda-gsch2pcb-project',
- 'g2p': 'application-x-geda-gsch2pcb-project',
- 'pcb': 'application-x-pcb-layout',
- 'pcb.net': 'application-x-pcb-netlist',
- 'gbr': 'application-x-gerber',
- 'gerber': 'application-x-gerber',
- 'cnc': 'application-x-excellon',
- 'net': 'application-x-pcb-netlist',
- 'exc': 'application-x-excellon',
- 'fp': 'application-x-pcb-footprint'}
-
-
- def cb_not_implemented(self, gedamanager):
- """
- Method to let the user know that the selected feature is not
- implemented yet.
- """
- dialog = gtk.MessageDialog(gedamanager.window,
- (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
- gtk.MESSAGE_INFO,
- gtk.BUTTONS_OK,
- gtk.STOCK_DIRECTORY)
- dialog.set_markup('<b>The selected feature is currently not implemented.\nUnder construction.</b>')
- dialog.show()
- response = dialog.run()
- dialog.destroy()
-
-
- def get_time(self):
- """ Method returns a string of the current time. """
- return time.asctime(time.localtime(time.time()))
-
-
- def get_filename_from_filepath(self, path):
- """!
- Method to return the node name from the path.
- @param path path to the node
- @return filename of the node without an extension
- """
- if '/' in path:
- return path.split('/')[-1]
- else:
- return ''
-
- def load_image(self, filepath):
- """!
- Method to load the image for filepath.
- @param filepath filepath for the node file
- @return icon_lut value for the filepath type
- """
- if '.' in filepath:
- ext = filepath.split('.')[-1]
- if ext not in self.icon_lut:
- return self.icon_lut['other']
- else:
- return self.icon_lut[ext]
- elif filepath in self.configfiles:
- return self.icon_lut['config']
- else:
- return self.icon_lut['folder']
-
-
- def get_status_image(self, gedamanager, highlighted_source):
- """!
- Method to get the status image for the process.
- @param gedamanager current gEDAManager instance
- @param highlighted_source currently selected node in the 'Sources' tree view.
- @return icon from the self.icon_lut structure
- """
- icon = gtk.IconTheme()
- if highlighted_source in gedamanager.project.dependency_status:
- if gedamanager.project.dependency_status[highlighted_source] != None:
- if gedamanager.project.dependency_status[highlighted_source]:
- return icon.load_icon(self.icon_lut['updated'], 22, 0)
- else:
- return icon.load_icon(self.icon_lut['outdated'], 22, 0)
-
-
- def flatten(self, lst):
- """!
- Method to flatten a nested list with tuple or list elements.
- @param lst nested list to flatten
- """
- for elem in lst:
- if type(elem) in (tuple, list):
- for i in self.flatten(elem):
- yield i
- else:
- yield elem
-
-
- @exceptions
- def is_filename_in_dependencies(self, gedamanager, filename, delete=False):
- """!
- Method to determine if the given filename is in the project's
- dependencies.
- @param gedamanager current gEDAManager instance
- @param filename name of the file under investigation
- @return True or False
- """
- # TODO -- this still needs fixing for the delete part
- # Need to iterate through to see if the filename is in the tree
- if filename != None:
- for row in gedamanager.dependencies:
- if row[0] == filename:
- if delete:
- pass
- #del gedamanager.dependencies[row],
- return True
- row_iter = row.iterchildren()
- if row_iter != None: # We have children in this row
- child_list = self.child_recurse(row_iter, 0)
- if child_list != None:
- child_list = [x for x in child_list if x != None]
- for x in child_list:
- if x == filename:
- if delete:
- pass
- #del gedamanager.dependencies[x]
- #gedamanager.dependencies.remove(iter_remove)
- return True
- return False
-
-
- def child_recurse(self, row_iter, index):
- """!
- Method to iterate recursively over child nodes.
- @param row_iter gtk.TreeModelRowIter object
- @param index index of the row to add to the returned list
- @return list of child nodes
- """
- child_list = []
- while True:
- try:
- child_row = row_iter.next()
- child_list.append(child_row[index])
- child_row_iter = child_row.iterchildren()
- if child_row_iter != None:
- child_list.append(self.child_recurse(child_row_iter, index))
- except StopIteration:
- break
- for x in child_list:
- if x == None:
- child_list.remove(x)
- if child_list != []:
- return child_list
-
-
- @exceptions
- def update_file_list(self, gedamanager, index=None, filepath=None):
- """!
- Method to update the gEDA Manager's project file list any time
- the 'Sources' tree view is changed.
- @param gedamanager current gEDAManager instance
- @param index index -- (0 = add copy source, 1 = delete source,
- 2 = delete folder, 3 = add a new source, 4 = remove source,
- 5 = remove folder)
- @param filepath filepath of the source to copy
- """
- ## TODO -- rip this functionality out and put into the gedamanager class
- ## or put that functionality in here. Currently I have cb_delete_folder
- ## etc in the gedamanager class
- selection = gedamanager.sources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- selected_node = gedamanager.sources.get_value(selection_iter, 2)
- else:
- return
- if filepath != None:
- filename = self.get_filename_from_filepath(filepath) # Files
- else:
- filename = self.get_filename_from_filepath(selected_node) # Folders
- icon = gtk.IconTheme()
- image = icon.load_icon(self.load_image(filename), 22, 0)
- path = selected_node + '/' + filename
-
- # Might want to extract this out to the gEDAManager class for
- # consistency
- if index == 0:
- # Logic here for copying the file to the selected_node's folder
- # First check that a file with the same name does not exist
- files = os.listdir(selected_node)
- if filename not in files:
- os.system('cp ' + filepath + ' ' + selected_node)
- gedamanager.output_textbuffer.insert(gedamanager.output_textiter, self.get_time() + ':\n' + 'Added copy of source:' + filepath + ' to ' + selected_node + '.\n')
- elif filepath == selected_node + '/' + filename:
- gedamanager.output_textbuffer.insert(gedamanager.output_textiter, self.get_time() + ':\n' + 'Added copy of source:' + filepath + ' to project.\n')
- else:
- gedamanager.output_textbuffer.insert(gedamanager.output_textiter, self.get_time() + ':\n' + filename + ' is already present in the directory: ' + selected_node + '.\n')
- elif index == 1:
- # Logic here to add a new source
- files = os.listdir(selected_node)
- if filename not in files:
- os.system('touch ' + filepath)
- gedamanager.output_textbuffer.insert(gedamanager.output_textiter, self.get_time() + ':\n' + 'Added new source:' + filepath + ' to ' + selected_node + '.\n')
- else:
- gedamanager.output_textbuffer.insert(gedamanager.output_textiter, self.get_time() + ':\n' + filename + ' is already present in the directory: ' + selected_node + '.\n')
-
- # Expand the 'Sources' tree view
- gedamanager.sources_tree.expand_all()
- # Now save the project since the new update file_list is made
- gedamanager.project.save()
-
-
- def get_processes_tree(self, gedamanager, selected_node=None, ext=None, folder=None, clear=None):
- """!
- Method to populate the 'Processes' tree view in the gEDA Manager.
- @param gedamanager current gEDAManager instance
- @param selected_node selected node in the 'Sources' tree view
- @param ext filename extension for the currently selected node
- in the 'Sources' tree view
- @param folder flag used to let the method know whether or not a
- folder has been selected
- @param clear paramater that is used to force a clearing of the
- processes model
- """
- current_directory = os.getcwd()
- os.chdir(self.directory)
- if clear:
- gedamanager.processes.clear()
- icon = gtk.IconTheme()
-
- if ext == None and folder != None:
- selection = gedamanager.sources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- selected_node = gedamanager.sources.get_value(selection_iter, 2)
-
- # Iterate over the folder to see what types of files they have
- # and build the tree this way.
- files = os.listdir(selected_node)
- extensions = []
- for f in files:
- if not f.endswith(('~','-')):
- ext = f.split('.')[-1]
- if ext not in extensions:
- extensions.append(ext)
- for ext in extensions:
- # recursively structure the tree
- if ext in self.icon_lut:
- self.get_processes_tree(gedamanager, selected_node, ext, True)
- else:
- print 'self.icon_lut does not contain:', ext
- return
-
- if ext == 'sch':
- # Parent folders
- simulation = gedamanager.processes.append(None, ['Simulate', None, None])
- create_pcb = gedamanager.processes.append(None, ['Create PCB', None, None])
- create_netlist = gedamanager.processes.append(None, ['Create Netlist', None, None])
- modify_attributes = gedamanager.processes.append(None, ['Modify Attributes', None, None])
-
- # Simulate
- image = icon.load_icon(self.icon_lut['spice'], 22, 0)
- gedamanager.processes.append(simulation, ['gspiceui', image, None])
-
- # PCB
- image = icon.load_icon(self.icon_lut['g2p'], 22, 0)
- gedamanager.processes.append(create_pcb, ['gsch2pcb workflow', image, None])
-
- # Netlists
- image = icon.load_icon(self.icon_lut['net'], 22, 0)
- gnetlist = gedamanager.processes.append(create_netlist, ['gnetlist', image, None])
- for netlist in sorted(self.netlists):
- gedamanager.processes.append(gnetlist, [netlist, None, None])
-
- # Modify attributes
- image = icon.load_icon(self.icon_lut['other'], 22, 0) #refdes -- TODO
- gedamanager.processes.append(modify_attributes, ['refdes_renum', None, None])
- image = icon.load_icon(self.icon_lut['other'], 22, 0) #grenum -- TODO
- gedamanager.processes.append(modify_attributes, ['grenum', None, None])
- image = icon.load_icon(self.icon_lut['gattrib'], 22, 0)
- gedamanager.processes.append(modify_attributes, ['gattrib', image, None])
-
- elif ext == 'pcb':
- # gsch2pcb
- status_image = self.get_status_image(gedamanager, selected_node)
- export = gedamanager.processes.append(None, ['Update PCB (gsch2pcb)', None, status_image])
- # Export
- export = gedamanager.processes.append(None, ['Export', None, None])
- gerber = gedamanager.processes.append(export, ['RS-274X (Gerber) file(s)', None, None])
- # May need to add for bom1 and bom2
- bom = gedamanager.processes.append(export, ['Bill of Materials (BOM) file(s)', None, None])
- nelma = gedamanager.processes.append(export, ['Numerical analysis (Nelma) file(s)', None, None])
- png = gedamanager.processes.append(export, ['GIF/JPEG/PNG file(s)', None, None])
- ps = gedamanager.processes.append(export, ['Postscript file(s)', None, None])
- eps = gedamanager.processes.append(export, ['Encapsulated Postscript file(s)', None, None])
- # Print
- _print = gedamanager.processes.append(None, ['Print (lpr)', None, None])
-
- elif ext == 'gbr':
- pass # Decide if any processes later
- elif ext == 'sym':
- # Parent folders
- check_symbols = gedamanager.processes.append(None, ['Check Symbols', None, None])
- image = icon.load_icon(self.icon_lut['sym'], 22, 0)
- gedamanager.processes.append(check_symbols, ['gsymcheck', image, None])
-
- elif ext == 'v':
- # Parent folders
- compile_source = gedamanager.processes.append(None, ['Compile Verilog', None, None])
-
- comsim_source = gedamanager.processes.append(None, ['Compile and Simulate Verilog', None, None])
- image = icon.load_icon(self.icon_lut['icarus'], 22, 0)
- gedamanager.processes.append(compile_source, ['icarus-compile', image, None])
- gedamanager.processes.append(comsim_source, ['icarus-compile->gtkwave-simulate', image, None])
-
- elif ext == 'vcd':
- # Parent folders
- # TODO -- need to find out if this is a from a .vhd file
- # or a .v file. Then either put a ghdl icon or icarus icon
- simulate = gedamanager.processes.append(None, ['Simulate', None, None])
- image = icon.load_icon(self.icon_lut['icarus'], 22, 0)
- gedamanager.processes.append(simulate, ['iverilog', image, None])
-
- elif ext == 'vhd' or ext == 'vhdl':
- # Parent folders
- compile_source = gedamanager.processes.append(None, ['Compile VHDL', None, None])
-
- comsim_source = gedamanager.processes.append(None, ['Compile and Simulate VHDL', None, None])
- image = icon.load_icon(self.icon_lut['ghdl'], 22, 0)
- gedamanager.processes.append(compile_source, ['ghdl-compile', image, None])
- gedamanager.processes.append(comsim_source, ['ghdl-compile->gtkwave-simulate', image, None])
-
- os.chdir(current_directory)
-
-
- def cb_sources_row_activated(self, widget, path, view_column, gedamanager):
- """!
- Event occurs when 'row-activated' signal is emitted or a user double
- clicks on a treeview row.
- @param widget widget that threw the event
- @param path path of the row of the cell to be activated in the gtk.TreeView
- object
- @param view_column gtk.TreeViewColumn of the cell to be
- @param gedamanager current gEDAManager instance
- activated
- """
- selected_node = gedamanager.sources[path][2]
- filename = gedamanager.sources[path][1]
- if '.' in filename: # We have a file
- ext = filename.split('.')[-1]
- elif filename in self.configfiles:
- ext = 'config'
- else: # We have a folder
- ext = 'folder'
- self.run_command(gedamanager, selected_node, None, ext)
-
-
- def cb_processes_row_activated(self, widget, path, view_column, gedamanager):
- """!
- Event occurs when 'row-activated' signal is emitted or a user double
- clicks on a treeview row.
- @param widget widget that threw the event
- @param path path of the row of the cell to be activated in the gtk.TreeView
- object
- @param view_column gtk.TreeViewColumn of the cell to be
- activated
- @param gedamanager current gEDAManager instance
- """
- selected_node = gedamanager.processes[path][0]
- selection = gedamanager.sources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- highlighted_source = gedamanager.sources.get_value(selection_iter, 2)
- if highlighted_source not in gedamanager.project.dependency_list:
- gedamanager.project.dependency_status[highlighted_source] = True
- gedamanager.project.dependency_list[highlighted_source] = []
- self.run_command(gedamanager, selected_node, highlighted_source)
-
-
- @exceptions
- def run_command(self, gedamanager, filepath, highlighted_source=None, ext=None):
- """!
- Method to run commands for 'Processes' and 'Sources'.
- @param gedamanager current gEDAManager instance
- @param filepath selected 'Sources' or 'Processes' node
- @param highlighted_source highlighted 'Sources' node that
- is being used for the current process
- @param ext extension of the selected file
- """
- files = ['net','log','bom','bom1','bom2','v','vhd','gm','txt','cmd']
- # Sources
- if ext != None:
- os.chdir(filepath.rpartition('/')[0])
- if ext == 'sch' or ext == 'sym':
- if gedamanager.tools['sch'] == None or gedamanager.tools['sch'].poll() == 0:
- gedamanager.tools['sch'] = Popen(['gschem', filepath])
- elif gedamanager.tools['sch'].poll() == None: # Process is still running
- pass
- elif ext == 'pcb':
- if gedamanager.tools['pcb'] == None or gedamanager.tools['pcb'].poll() == 0:
- gedamanager.tools['pcb'] = Popen(['pcb', filepath])
- elif gedamanager.tools['pcb'].poll() == None: # Process is still running
- pass
- elif ext == 'gbr':
- if gedamanager.tools['gerbv'] == None or gedamanager.tools['gerbv'].poll() == 0:
- gedamanager.tools['gerbv'] = Popen(['gerbv', filepath])
- elif gedamanager.tools['gerbv'].poll() == None: # Process is still running
- print 'gerbv is open'
- elif (ext in files or ext in self.configfiles):
- if gedamanager.settings.editor == None:
- dialog = gtk.MessageDialog(gedamanager.window,
- (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
- gtk.MESSAGE_INFO,
- gtk.BUTTONS_OK,
- gtk.STOCK_DIRECTORY)
- dialog.set_markup('<b>Please go to Edit->Preferences and choose a default text editor.</b>')
- dialog.show()
- response = dialog.run()
- dialog.destroy()
-
- # Need to put some logic here to make sure it is a valid program
- else: #gedamanager.tools['editor'] != None:
- Popen([gedamanager.settings.editor, filepath])
-
- else: # Processes
- os.chdir(highlighted_source.rpartition('/')[0])
- program = filepath
- # Netlists
- if program in self.netlists: # use gnetlist
- subproc = Popen(['gnetlist', '-v','-g',program,highlighted_source], stdout=PIPE)
- gedamanager.output_textbuffer.insert(gedamanager.output_textiter, self.get_time() + ' and output from ' + program + ':\n' + subproc.communicate()[0] + '\n')
- elif program == 'ghdl-compile':
- # TODO
- self.cb_not_implemented(gedamanager)
- elif program == 'ghdl-compile->gtkwave-simulate':
- # TODO
- self.cb_not_implemented(gedamanager)
- pass
- elif program == 'icarus-compile':
- # TODO
- self.cb_not_implemented(gedamanager)
- pass
- elif program == 'icarus-compile->gtkwave-simulate':
- # TODO
- self.cb_not_implemented(gedamanager)
- pass
- elif program == 'gattrib':
- if gedamanager.tools['gattrib'] == None or gedamanager.tools['gattrib'].poll() == 0:
- gedamanager.tools['gattrib'] = Popen([program, highlighted_source], stdout=PIPE)
- gedamanager.output_textbuffer.insert(gedamanager.output_textiter, self.get_time() + ' and output from ' + program + ':\n' + gedamanager.tools['gattrib'].communicate()[0] + '.\n')
- elif gedamanager.tools['gattrib'].poll() == None: # Process is still running
- pass
- elif program == 'gsymcheck':
- arg = '-v ' + highlighted_source
- subproc = Popen([program, arg], stdout=PIPE)
- gedamanager.output_textbuffer.insert(gedamanager.output_textiter, self.get_time() + ' and output from ' + program + ':\n' + subproc.communicate()[0] + '.\n')
- elif program == 'gsch2pcb workflow':
- self.gsch2pcb = Gsch2pcb(gedamanager, highlighted_source)
- elif program == 'Update PCB (gsch2pcb)':
- # Only run if the highlighted_souce is outdated
- if not gedamanager.project.dependency_status[highlighted_source]:
- files_before = os.listdir(highlighted_source.rpartition('/')[0])
- schematics_list = []
- # TODO
- if schematics_list:
- schematics = ''
- for sch in schematics_list:
- schematics += sch + ' '
-
- name = filename.split('.')[0]
- print 'name:',name
- print 'schematics:',schematics
- subproc = Popen(['gsch2pcb', '-v','-v','-o',name,schematics]).wait()
- files_after = os.listdir(highlighted_source.rpartition('/')[0])
- files = [x for x in files_after if x not in files_before]
- # Add any new files to the sources tree view if any
- if files:
- icon = gtk.IconTheme()
- selection = gedamanager.sources_tree.get_selection()
- model, selection_iter = selection.get_selected()
- if isinstance(selection_iter, gtk.TreeIter):
- parent_iter = gedamanager.sources.iter_parent(selection_iter)
- wanted = ['pcb','new.pcb','net']
- new_files = []
- new_files.append(True)
- for f in files:
- if f.endswith('new.pcb'):
- ext = 'new.pcb'
- else:
- ext = f.split('.')[-1]
- if ext in wanted:
- filepath = directory + '/' + f
- image = icon.load_icon(self.icon_lut[ext], 22, 0)
- # Don't think I need the below
-# gedamanager.dependencies.append(None, [f, filepath])
- # Need to see if there are any new files
- new_files.append(f)
- print 'new_files:',new_files
- else:
- print 'no new files'
-
- else:
- self.cb_not_implemented(gedamanager)
- ## TODO I will need to change the below since 'program' may
- ## not be an actual program
- ## subproc = Popen([program, highlighted_source])
-
- ## def update_dependency_list(self, gedamanager, filename, flag=False):
- ## """!
- ## Method to update the dependencies for filename.
- ## @param filename file that will have its dependencies updated
- ## or list of filenames that will have its dependencies updated
- ## @param flag sets status of filename
- ## """
- ## if isinstance(filename, list):
- ## for f in filename:
- ## gedamanager.project.dependency_list[f][0] = flag
- ## for x in gedamanager.project.dependency_list[f][1:]:
- ## self.update_dependency_list(gedamanager, x, False)
- ## else:
- ## # We just need to create a new list and set that as the value
- ## gedamanager.project.dependency_list[filename][0] = flag
- ## for x in gedamanager.project.dependency_list[filename][1:]:
- ## # recurse over files and make out of date
- ## self.update_dependency_list(gedamanager, x, False)
-
-
- ## def add_to_dependency_list(self, gedamanager, filename):
- ## """!
- ## Method to add a file to the project's dependency_list.
- ## @param filename file to add to project.dependency_list
- ## """
- ## # add file to the dependency_list
- ## if filename not in gedamanager.project.dependency_list:
- ## gedamanager.project.dependency_list[filename] = [True, [], []]
-
diff --git a/src/utils/Callbacks.py b/src/utils/Callbacks.py
new file mode 100644
index 0000000..1d1d163
--- /dev/null
+++ b/src/utils/Callbacks.py
@@ -0,0 +1,964 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.utils.Callbacks
+#Callbacks for the gEDA Manager
+#@author Newell Jensen
+
+import gtk, shutil, sys, gnomevfs
+from src.utils.Helpers import *
+from src.gui.NewProject import NewProject
+
+######################################################
+# Callback Methods
+######################################################
+
+def cb_show_about_dialog(menuitem, mw):
+ """!
+ Event handler for About menu button.
+ @param menuitem about menuitem that threw the event
+ @param mw Mw object
+ """
+ mw.aboutdialog.show()
+ mw.aboutdialog.run()
+ mw.aboutdialog.hide()
+
+
+def cb_url_geda_wiki(menuitem, data=None):
+ """!
+ Event handler for gEDA Wiki.
+ @param menuitem menuitem that threw the event
+ @param data optional user data to pass in
+ """
+ gnomevfs.url_show('http://geda.seul.org/wiki/')
+
+
+def cb_url_geda_documentation(menuitem, data=None):
+ """!
+ Event handler for gEDA Documentation.
+ @param menuitem menuitem that threw the event
+ @param data optional user data to pass in
+ """
+ gnomevfs.url_show('http://geda.seul.org/wiki/geda:documentation')
+
+
+def cb_url_geda_manager_blog(menuitem, data=None):
+ """!
+ Event handler for gEDA Manager.
+ @param menuitem menuitem that threw the event
+ @param data optional user data to pass in
+ """
+ gnomevfs.url_show('http://www.gempillar.com')
+
+
+def cb_url_geda_manager_api_documentation(menuitem, data=None):
+ """!
+ Event handler for gEDA Manager.
+ @param menuitem menuitem that threw the event
+ @param data optional user data to pass in
+ """
+ gnomevfs.url_show('http://www.gempillar.com/docs/geda-manager')
+
+
+def cb_new_project(menuitem, mw):
+ """!
+ Event handler for 'New Project'.
+ @param menuitem menuitem that threw the event
+ @param mw current mw instance
+ """
+ mw.project.save()
+ NewProject(mw)
+
+
+def cb_open_project(menuitem, mw):
+ """!
+ Event handler for 'Open Project'.
+ @param menuitem menuitem that threw the event
+ @param mw current mw instance
+ """
+ mw.project.save()
+ dialog = gtk.FileChooserDialog('Open...',
+ mw,
+ gtk.FILE_CHOOSER_ACTION_OPEN,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+
+ dialog.set_default_response(gtk.RESPONSE_OK)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("Project files (*.gm)")
+ file_filter.add_pattern('*.gm')
+ dialog.add_filter(file_filter)
+
+ response = dialog.run()
+ if response == gtk.RESPONSE_OK:
+ set_project(dialog.get_filename(), mw)
+ dialog.destroy()
+
+
+def cb_close_project(menuitem, mw):
+ """!
+ Event handler for 'Close Project'.
+ @param menuitem menuitem that threw the event
+ @param mw Mw object
+ @param mw current mw instance
+ """
+ write_logs(mw)
+ mw.project.save()
+ mw.project.close()
+ # clear the processes mw
+ mw.processes.clear()
+
+
+def cb_project_closed(widget, event, mw):
+ """!
+ Event occurs when a Project object is closed
+ @param widget widget that threw the event
+ @param event event that was thrown
+ @param mw Mw object
+ """
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\n' + 'Project closed.\n')
+ set_menu_defaults(mw)
+ set_sources_tree_to_project(mw)
+ set_dependencies_tree_to_project(mw)
+
+
+def cb_project_opened(widget, event, mw):
+ """!
+ Event occurs when a Project object is opened
+ @param widget widget that threw the event
+ @param event event that was thrown
+ @param mw Mw object
+ """
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\n' + 'Project ' + mw.project.name + ' opened.\n')
+ set_menu_defaults(mw)
+ set_sources_tree_to_project(mw)
+ set_dependencies_tree_to_project(mw)
+
+
+def cb_project_created(widget, event, mw):
+ """!
+ Event occurs when a Project object is created
+ @param widget widget that threw the event
+ @param event event that was thrown
+ """
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\nProject ' + mw.project.name + ' created.\n')
+ set_menu_defaults(mw)
+ set_sources_tree_to_project(mw)
+ set_dependencies_tree_to_new_project(mw)
+
+
+def cb_cursor_changed(widget, mw):
+ """!
+ Event occurs when the cursor changes in the treeview.
+ @param widget widget that threw the event
+ """
+ selection = mw.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ mw.processes_tree.set_sensitive(True)
+ selected_node = mw.sources.get_value(selection_iter, 2)
+ filename = get_filename_from_filepath(selected_node)
+ if '.' in filename and not filename.endswith(('.gm','.log')):
+ # Logic to call function to find what type of file it is
+ # and then to populate the according tree view
+ ext = filename.split('.')[-1]
+ get_processes_tree(mw, selected_node, ext, None, True)
+ # Update 'Processes: ' for the 'Processes' tree
+ column = mw.processes_tree.get_column(0)
+ column.set_title('Processes for: ' + filename)
+ column = mw.processes_tree.get_column(2)
+ column.set_title('status')
+ else: # We have the project folder
+ # Clear out the columns
+ column = mw.processes_tree.get_column(0)
+ column.set_title('')
+ column = mw.processes_tree.get_column(2)
+ column.set_title('')
+ # clear out the processes
+ mw.processes.clear()
+ else: # Set the processes to invisible
+ mw.processes_tree.set_sensitive(False)
+
+
+
+def cb_row_changed(model, path, iter, mw):
+ """!
+ Event occurs when the columns change in the dependencies treeview.
+ @param model gtk.TreeStore model for the dependencies
+ """
+ # We only want a file to appear once
+ def recurse_model(row_iter, row):
+ try:
+ for new_row in row_iter:
+ if new_row[1] not in files:
+ new_dep_list[row[1]].append(new_row[1])
+ files.append(new_row[1])
+ new_row_iter = new_row.iterchildren()
+ if new_row_iter != None:
+ recurse_model(new_row_iter, new_row)
+ except StopIteration:
+ print 'StopIteraion'
+ except:
+ print 'except:', sys.exc_info()[0]
+
+ files = []
+ new_dep_list = {}
+ for row in model:
+ if row[1] not in files:
+ new_dep_list[row[1]] = []
+ files.append(row[1])
+ row_iter = row.iterchildren()
+ if row_iter != None:
+ recurse_model(row_iter, row)
+ mw.project.dependency_list = new_dep_list
+
+
+def cb_switch_page(notebook, page, page_num, mw):
+ if page_num == 1: # Dependencies notebook tab
+ selection = mw.sources_tree.get_selection()
+ selection.unselect_all()
+ mw.processes.clear()
+ column = mw.processes_tree.get_column(0)
+ column.set_title('')
+ column = mw.processes_tree.get_column(2)
+ column.set_title('')
+
+
+# TODO -- try to clean up this method
+def get_processes_tree(mw, selected_node=None, ext=None, folder=None, clear=None):
+ """!
+ Method to populate the 'Processes' tree view in the gEDA Manager.
+ @param mw Mw object
+ @param selected_node selected node in the 'Sources' tree view
+ @param ext filename extension for the currently selected node
+ in the 'Sources' tree view
+ @param folder flag used to let the method know whether or not a
+ folder has been selected
+ @param clear paramater that is used to force a clearing of the
+ processes model
+ """
+ current_directory = os.getcwd()
+ os.chdir(directory)
+ if clear:
+ mw.processes.clear()
+ icon = gtk.IconTheme()
+
+ if ext == None and folder != None:
+ selection = mw.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = mw.sources.get_value(selection_iter, 2)
+
+ # Iterate over the folder to see what types of files they have
+ # and build the tree this way.
+ files = os.listdir(selected_node)
+ extensions = []
+ for f in files:
+ if not f.endswith(('~','-')):
+ ext = f.split('.')[-1]
+ if ext not in extensions:
+ extensions.append(ext)
+ for ext in extensions:
+ # recursively structure the tree
+ if ext in mw.icons.icon_lut:
+ get_processes_tree(mw, selected_node, ext, True)
+ else:
+ print 'mw.icons.icon_lut does not contain:', ext
+ return
+
+ if ext == 'sch':
+ simulation = mw.processes.append(None, ['Simulate', None, None])
+ create_pcb = mw.processes.append(None, ['Create PCB', None, None])
+ create_netlist = mw.processes.append(None, ['Create Netlist', None, None])
+ modify_attributes = mw.processes.append(None, ['Modify Attributes', None, None])
+ image = icon.load_icon(mw.icons.icon_lut['gspiceui'], 22, 0)
+ mw.processes.append(simulation, ['gspiceui', image, None])
+ image = icon.load_icon(mw.icons.icon_lut['g2p'], 22, 0)
+ mw.processes.append(create_pcb, ['gsch2pcb workflow', image, None])
+ image = icon.load_icon(mw.icons.icon_lut['net'], 22, 0)
+ gnetlist = mw.processes.append(create_netlist, ['gnetlist', image, None])
+ for netlist in sorted(netlists):
+ mw.processes.append(gnetlist, [netlist, None, None])
+
+ image = icon.load_icon(mw.icons.icon_lut['other'], 22, 0) #refdes -- TODO
+ mw.processes.append(modify_attributes, ['refdes_renum', None, None])
+ image = icon.load_icon(mw.icons.icon_lut['other'], 22, 0) #grenum -- TODO
+ mw.processes.append(modify_attributes, ['grenum', None, None])
+ image = icon.load_icon(mw.icons.icon_lut['gattrib'], 22, 0)
+ mw.processes.append(modify_attributes, ['gattrib', image, None])
+ elif ext == 'pcb':
+ # TODO -- status image commented out until dependency issues
+ # are taken care of
+ ## status_image = get_status_image(mw, selected_node)
+ ## export = mw.processes.append(None, ['Update PCB (gsch2pcb)', None, status_image])
+ export = mw.processes.append(None, ['Update PCB (gsch2pcb)', None, None])
+ export = mw.processes.append(None, ['Export', None, None])
+ gerber = mw.processes.append(export, ['RS-274X (Gerber) file(s)', None, None])
+ # May need to add for bom1 and bom2
+ bom = mw.processes.append(export, ['Bill of Materials (BOM) file(s)', None, None])
+ nelma = mw.processes.append(export, ['Numerical analysis (Nelma) file(s)', None, None])
+ png = mw.processes.append(export, ['GIF/JPEG/PNG file(s)', None, None])
+ ps = mw.processes.append(export, ['Postscript file(s)', None, None])
+ eps = mw.processes.append(export, ['Encapsulated Postscript file(s)', None, None])
+ _print = mw.processes.append(None, ['Print (lpr)', None, None])
+
+ elif ext == 'gbr':
+ pass # TODO --> any process for this?
+ elif ext == 'sym':
+ check_symbols = mw.processes.append(None, ['Check Symbols', None, None])
+ image = icon.load_icon(mw.icons.icon_lut['sym'], 22, 0)
+ mw.processes.append(check_symbols, ['gsymcheck', image, None])
+ elif ext == 'v':
+ compile_source = mw.processes.append(None, ['Compile Verilog', None, None])
+ comsim_source = mw.processes.append(None, ['Compile and Simulate Verilog', None, None])
+ image = icon.load_icon(mw.icons.icon_lut['iverilog'], 22, 0)
+ mw.processes.append(compile_source, ['icarus-compile', image, None])
+ mw.processes.append(comsim_source, ['icarus-compile->gtkwave-simulate', image, None])
+ elif ext == 'vvp':
+ simulate = mw.processes.append(None, ['Simulate', None, None])
+ image = icon.load_icon(mw.icons.icon_lut['iverilog'], 22, 0)
+ mw.processes.append(simulate, ['iverilog', image, None])
+ elif ext == 'vhd' or ext == 'vhdl':
+ compile_source = mw.processes.append(None, ['Compile VHDL', None, None])
+ comsim_source = mw.processes.append(None, ['Compile and Simulate VHDL', None, None])
+ image = icon.load_icon(mw.icons.icon_lut['ghdl'], 22, 0)
+ mw.processes.append(compile_source, ['ghdl-compile', image, None])
+ mw.processes.append(comsim_source, ['ghdl-compile->gtkwave-simulate', image, None])
+ elif ext == 'net':
+ simulation = mw.processes.append(None, ['Simulate', None, None])
+ image = icon.load_icon(mw.icons.icon_lut['gspiceui'], 22, 0)
+ mw.processes.append(simulation, ['gspiceui', image, None])
+
+ os.chdir(current_directory)
+
+
+def cb_sources_row_activated(widget, path, view_column, mw):
+ """!
+ Event occurs when 'row-activated' signal is emitted or a user double
+ clicks on a treeview row.
+ @param widget widget that threw the event
+ @param path path of the row of the cell to be activated in the gtk.TreeView
+ object
+ @param view_column gtk.TreeViewColumn of the cell to be
+ @param mw Mw object
+ """
+ selected_node = mw.sources[path][2]
+ filename = mw.sources[path][1]
+ if '.' in filename: # We have a file
+ ext = filename.split('.')[-1]
+ elif filename in configfiles:
+ ext = 'config'
+ else: # We have a folder
+ ext = 'folder'
+ run_command(mw, selected_node, None, ext)
+
+
+def cb_processes_row_activated(widget, path, view_column, mw):
+ """!
+ Event occurs when 'row-activated' signal is emitted or a user double
+ clicks on a treeview row.
+ @param widget widget that threw the event
+ @param path path of the row of the cell to be activated in the gtk.TreeView
+ object
+ @param view_column gtk.TreeViewColumn of the cell to be
+ activated
+ """
+ selected_node = mw.processes[path][0]
+ selection = mw.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ highlighted_source = mw.sources.get_value(selection_iter, 2)
+ if highlighted_source not in mw.project.dependency_list:
+ mw.project.dependency_status[highlighted_source] = True
+ mw.project.dependency_list[highlighted_source] = []
+ run_command(mw, selected_node, highlighted_source)
+
+
+def cb_preferences(menuitem, mw):
+ """!
+ Event occurs when the user opens up the preferences menu.
+ @param menuitem menuitem that threw the event
+ @param data optional user data to pass in
+ """
+ def new_source_cursor_changed(newsources_tree):
+ selection = newsources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ newsource = model.get_value(selection_iter, 1)
+
+ if mw.settings.editor != None:
+ old_editor = mw.settings.editor
+ else:
+ old_editor = None
+
+ def response_to_dialog(entry, dialog, response):
+ dialog.response(response)
+
+ entry = gtk.Entry()
+ if mw.settings.editor != None:
+ entry.set_text(mw.settings.editor)
+ entry.show()
+
+ def cb_filebutton_selection_changed(filechooser, entry):
+ mw.settings.editor = filebutton.get_filename()
+ entry.delete_text(0,-1)
+ entry.set_text(mw.settings.editor)
+
+ dialog = gtk.MessageDialog(mw,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_OTHER,
+ gtk.BUTTONS_OK_CANCEL,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>Preference settings:</b>')
+ dialog.set_title('Preferences')
+ hbox = gtk.HBox()
+ hbox.show()
+
+ filebutton = gtk.FileChooserButton('Text Editor')
+ filebutton.show()
+ filebutton.connect('selection-changed',
+ cb_filebutton_selection_changed, entry)
+ filebutton.set_local_only(True)
+ filebutton.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
+ hbox.pack_end(filebutton)
+
+ entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+ hbox.pack_end(entry)
+ label = gtk.Label('Text Editor:')
+ label.show()
+ hbox.pack_end(label)
+
+ dialog.vbox.pack_end(hbox, True, True, 0)
+ dialog.show()
+ dialog.run()
+ if old_editor != mw.settings.editor: # A change was made
+ new_text = mw.settings.editor
+ else:
+ new_text = entry.get_text()
+ dialog.destroy()
+
+ if new_text:
+ mw.settings.editor = new_text
+
+
+def update_file_list(mw, index=None, filepath=None):
+ """!
+ Method to update the gEDA Manager's project file list any time
+ the 'Sources' tree view is changed.
+ @param mw Mw object
+ @param index index -- (0 = add copy source, 1 = delete source,
+ 2 = delete folder, 3 = add a new source, 4 = remove source,
+ 5 = remove folder)
+ @param filepath filepath of the source to copy
+ """
+ selection = mw.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = mw.sources.get_value(selection_iter, 2)
+ else:
+ return
+ if filepath != None:
+ filename = get_filename_from_filepath(filepath) # Files
+ else:
+ filename = get_filename_from_filepath(selected_node) # Folders
+ icon = gtk.IconTheme()
+ image = icon.load_icon(load_image(filename), 22, 0)
+ path = selected_node + '/' + filename
+
+
+ # Expand the 'Sources' tree view
+ mw.sources_tree.expand_all()
+ # Now save the project since the new update file_list is made
+ mw.project.save()
+
+
+def cb_delete(menuitem, mw):
+ """!
+ Event handler for 'Delete'. This method will delete the file from the
+ filesystem.
+ @param menuitem that threw the event.
+ @param data optional to pass in.
+ """
+ selection = mw.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = mw.sources.get_value(selection_iter, 2)
+ os.system('rm ' + selected_node)
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\nDeleted ' + selected_node + '.\n')
+
+
+
+def cb_new_source(menuitem, mw):
+ """!
+ Event occurs when the user wants to add a source to the project
+ @param menuitem menutiem that threw the event
+ @param mw current Mw instance
+ """
+ def response_to_dialog(entry, dialog, response):
+ dialog.response(response)
+
+
+ dialog = gtk.MessageDialog(mw,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_QUESTION,
+ gtk.BUTTONS_OK_CANCEL,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>Please enter the new file name (extension will be added):</b>')
+ entry = gtk.Entry()
+ entry.show()
+ entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+ hbox = gtk.HBox()
+ hbox.show()
+ hbox.pack_end(entry)
+ label = gtk.Label('File name:')
+ label.show()
+ hbox.pack_end(label)
+
+ # Models for the Tree View
+ newsources = gtk.TreeStore(gtk.gdk.Pixbuf, str)
+ # Tree View
+ newsources_tree = gtk.TreeView(newsources)
+ newsources_tree.show()
+ # column headings
+ newsources_pixbuf = gtk.CellRendererPixbuf()
+ newsources_pixbuf.set_property('xalign', 0)
+ column = gtk.TreeViewColumn(None, newsources_pixbuf, pixbuf=0)
+ newsources_tree.append_column(column)
+ newsources_cell = gtk.CellRendererText()
+ column = gtk.TreeViewColumn('Source Type', newsources_cell, text=1)
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ newsources_tree.append_column(column)
+ # populate the tree view
+ icon = gtk.IconTheme()
+ image = icon.load_icon(mw.icons.icon_lut['pcb'], 22, 0)
+ newsources.append(None, [image, 'PCB (.pcb)'])
+ image = icon.load_icon(mw.icons.icon_lut['sch'], 22, 0)
+ newsources.append(None, [image, 'Schematic (.sch)'])
+ image = icon.load_icon(mw.icons.icon_lut['v'], 22, 0)
+ newsources.append(None, [image, 'Verilog (.v)'])
+ image = icon.load_icon(mw.icons.icon_lut['vhd'], 22, 0)
+ newsources.append(None, [image, 'VHDL (.vhd)'])
+ image = icon.load_icon(mw.icons.icon_lut['sym'], 22, 0)
+ newsources.append(None, [image, 'Symbol (.sym)'])
+ # I can add whatever I want but first need to figure out if this is
+ # something I would want to add
+ ## image = icon.load_icon(mw.icons.icon_lut['net'], 22, 0)
+ ## newsources.append(None, [image, 'Netlist (.net)'])
+
+ # add to the hbox
+ hbox.pack_start(newsources_tree, False, False)
+ dialog.vbox.pack_end(hbox, True, True, 0)
+
+ dialog.show()
+ response = dialog.run()
+ if response == gtk.RESPONSE_CANCEL:
+ dialog.destroy()
+ return
+ new_text = entry.get_text()
+ selection = newsources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ newsource = model.get_value(selection_iter, 1)
+ else:
+ newsource = None
+ dialog.destroy()
+
+ if new_text and newsource != None:
+ # Get the selected_node for the folder to add to
+ selection = mw.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = mw.sources.get_value(selection_iter, 2)
+ # Get the type of extension for the program to call
+ if '.' in new_text: # user may have overriden extension
+ return
+ else: # Need to find out what extension from the highlighted node
+ ext = newsource[newsource.find('.')+1:newsource.find(')')]
+ # Make sure a file with the same name doesn't already exist
+ filepath = selected_node + '/' + new_text + '.' + ext
+ filename = new_text + '.' + ext
+ # TODO -- patch up
+ ## # Logic here to add a new source
+ ## selection = mw.sources_tree.get_selection()
+ ## model, selection_iter = selection.get_selected()
+ ## if isinstance(selection_iter, gtk.TreeIter):
+ ## selected_node = mw.sources.get_value(selection_iter, 2)
+ ## else:
+ ## return
+ ## if filepath != None:
+ ## filename = get_filename_from_filepath(filepath) # Files
+ ## else:
+ ## filename = get_filename_from_filepath(selected_node) # Folders
+ ## icon = gtk.IconTheme()
+ ## image = icon.load_icon(load_image(filename), 22, 0)
+ ## path = selected_node + '/' + filename
+
+ files = os.listdir(selected_node)
+ if filename not in files:
+ os.system('touch ' + filepath)
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\n' + 'Added new source:' + filepath + ' to ' + selected_node + '.\n')
+ else:
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\n' + filename + ' is already present in the directory: ' + selected_node + '.\n')
+
+ run_command(mw, filepath, None, ext)
+ else:
+ dialog = gtk.MessageDialog(mw,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_INFO,
+ gtk.BUTTONS_OK,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>Please enter text and/or make sure a file type is selected.</b>')
+ dialog.show()
+ response = dialog.run()
+ dialog.destroy()
+
+
+
+def cb_add_copy_source(menuitem, mw):
+ """!
+ Event occurs when the user wants to add a source to the project
+ @param menuitem menuitem that threw the event
+ @param data optional user data to pass in
+ """
+ dialog = gtk.FileChooserDialog('Copy Existing Source To Project...',
+ mw,
+ gtk.FILE_CHOOSER_ACTION_OPEN,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+
+ dialog.set_default_response(gtk.RESPONSE_OK)
+ file_filters(dialog)
+ response = dialog.run()
+ if response == gtk.RESPONSE_OK:
+ filepath = dialog.get_filename()
+ # TODO -- patch up
+ ## selection = spd.sources_tree.get_selection()
+ ## model, selection_iter = selection.get_selected()
+ ## if isinstance(selection_iter, gtk.TreeIter):
+ ## selected_node = mw.sources.get_value(selection_iter, 2)
+ ## else:
+ ## return
+ ## if filepath != None:
+ ## filename = get_filename_from_filepath(filepath)
+ ## else:
+ ## filename = get_filename_from_filepath(selected_node)
+ ## icon = gtk.IconTheme()
+ ## image = icon.load_icon(load_image(filename), 22, 0)
+ ## path = selected_node + '/' + filename
+
+ ## files = os.listdir(selected_node)
+ ## if filename not in files:
+ ## os.system('cp ' + filepath + ' ' + selected_node)
+ ## mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\n' + 'Added copy of source:' + filepath + ' to ' + selected_node + '.\n')
+ ## elif filepath == selected_node + '/' + filename:
+ ## mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\n' + 'Added copy of source:' + filepath + ' to project.\n')
+ ## else:
+ ## mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\n' + filename + ' is already present in the directory: ' + selected_node + '.\n')
+
+
+ dialog.destroy()
+
+
+
+def cb_new_folder(action, mw):
+ """!
+ Event occurs when the user chooses to add a new folder to the project.
+ @param action gtk.Action object
+ """
+ def response_to_dialog(entry, dialog, response):
+ dialog.response(response)
+
+ selection = mw.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = mw.sources.get_value(selection_iter, 2)
+ if '.' in selected_node:
+ # This is not a folder
+ # YES, this is a hack and was put in place because
+ # we get some problems if the use right clicks on a node before
+ # it becomes highlighted.
+ return
+ os.chdir(selected_node)
+ dialog = gtk.MessageDialog(mw,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_QUESTION,
+ gtk.BUTTONS_OK_CANCEL,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>Please enter new folder name:</b>\nIf the folder name you choose exists\non disk in this directory it will deleted.')
+ entry = gtk.Entry()
+ entry.show()
+ entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+ hbox = gtk.HBox()
+ hbox.show()
+ hbox.pack_end(entry)
+ dialog.vbox.pack_end(hbox, True, True, 0)
+ dialog.show()
+ response = dialog.run()
+ text = entry.get_text()
+ if response == gtk.RESPONSE_OK and text.strip() != '':
+ filepath = selected_node + '/' + text
+ ## def delete_dependency_list_entry(arg, dirname, filenames):
+ ## """ function to delete the filenames from the dependency_list """
+ ## for f in filenames:
+ ## if f in mw.project.dependency_list and list(flatten(project.file_list)).count(f) == 1:
+ ## del mw.project.dependency_list[f]
+
+ # See if this directory already exists
+ if os.path.exists(filepath): # delete directory recursively
+ ## os.path.walk(filepath, delete_dependency_list_entry, None)
+ shutil.rmtree(filepath)
+ os.mkdir(filepath)
+ mw.project.save() # Saving the project takes
+ dialog.destroy()
+
+
+def cb_delete_folder(widget, mw):
+ """!
+ Event occurs when the user chooses to delete a folder from the project.
+ This method will delete the folder from the filesystem.
+ @param widget that threw the event.
+ """
+ selection = mw.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = mw.sources.get_value(selection_iter, 2)
+ exists = os.path.exists(selected_node)
+ if exists: # delete directory recursively
+ os.system('rm -rf ' + selected_node)
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\nDeleted ' + selected_node + '.\n')
+
+
+
+def cb_open_in_editor(action, mw):
+ """!
+ Event occurs when the user wants to open a source file in the editor.
+ @param action gtk.Action object involved with this event
+ """
+ selection = mw.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = mw.sources.get_value(selection_iter, 2)
+ # Run the command as if the file is a text file
+ run_command(mw, selected_node, None, 'txt')
+
+
+def cb_rename_folder(action, mw):
+ """!
+ Event handler for renaming a folder.
+ @param action gtk.Action object involved with this event
+ """
+ def response_to_dialog(entry, dialog, response):
+ dialog.response(response)
+
+ selection = mw.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ old_path = mw.sources.get_value(selection_iter, 2)
+ path = mw.sources.get_path(selection_iter)
+
+ dialog = gtk.MessageDialog(mw,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_QUESTION,
+ gtk.BUTTONS_OK_CANCEL,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>Please enter the new folder name:\n</b>')
+ entry = gtk.Entry()
+ entry.show()
+ entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+ hbox = gtk.HBox()
+ hbox.show()
+ hbox.pack_end(entry)
+ dialog.vbox.pack_end(hbox, True, True, 0)
+ dialog.show()
+ dialog.run()
+ new_text = entry.get_text()
+ dialog.destroy()
+ new_path = old_path.rpartition('/')[0] + '/' + new_text
+
+ if '.' not in new_text:
+ ## We are going to handle the project folder in cb_rename_folder
+ if old_path == project.directory:
+ # Project Folder
+ os.rename(old_path, new_path)
+ project_file = new_path + '/' + project.name + '.gm'
+ os.remove(project_file)
+ project.directory = new_path
+ project.name = new_text
+ ## project.file_list[0] = new_text
+ ## project.file_list[1][0] = new_text + '.gm'
+ project.save()
+ output_textbuffer.insert(output_textiter, 'Project changed from ' + old_path + ' to ' + new_path + '.\n')
+ else:
+ # Regular folder
+ if os.path.exists(new_path):
+ output_textbuffer.insert(output_textiter, 'Folder already exists with this name. Cannot rename.\n')
+ return
+ os.rename(old_path, new_path)
+
+
+def cb_rename(action, mw):
+ """!
+ Event handler for renaming a file.
+ @param action gtk.Action object involved with this event
+ """
+ def response_to_dialog(entry, dialog, response):
+ dialog.response(response)
+
+ selection = mw.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ old_path = mw.sources.get_value(selection_iter, 2)
+ path = mw.sources.get_path(selection_iter)
+
+ dialog = gtk.MessageDialog(mw,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_QUESTION,
+ gtk.BUTTONS_OK_CANCEL,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>Please enter the new name\n(include an extension for\nprogram to recognize file type):</b>')
+ entry = gtk.Entry()
+ entry.show()
+ entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+ hbox = gtk.HBox()
+ hbox.show()
+ hbox.pack_end(entry)
+ dialog.vbox.pack_end(hbox, True, True, 0)
+ dialog.show()
+ dialog.run()
+ new_text = entry.get_text()
+ dialog.destroy()
+ new_path = old_path.rpartition('/')[0] + '/' + new_text
+
+ if '.' in new_text and '.' in old_path:
+ # File
+ os.rename(old_path, new_path)
+ mw.output_textbuffer.insert(mw.output_textiter, old_path + ' changed to ' + new_path + '.\n')
+ elif not '.' in new_text and not '.' in old_path:
+ # Folder -- so image does not need to be changed
+ if os.path.exists(new_path):
+ mw.output_textbuffer.insert(mw.output_textiter, 'Folder already exists with this name. Cannot rename.\n')
+ return
+ os.rename(old_path, new_path)
+ mw.output_textbuffer.insert(mw.output_textiter, old_path + ' changed to ' + new_path + '.\n')
+
+
+def cb_popup_deactivate(popup_menu, merge_id, mw):
+ """!
+ Event occurs when the 'deactivate' signal is thrown from
+ the popup menu.
+ @param popup_menu is the popup_menu.
+ @param merge_id is the merge id from the popup uimanager.
+ """
+ # Remove the ui from the uimanager
+ mw.popup_uimanager.remove_ui(merge_id)
+
+
+def cb_button_press(widget, event, mw):
+ """!
+ This signal handler will be called when the treeview emits
+ a 'button_press_event' signal.
+ @param widget widget that threw the event
+ @param event event that was thrown
+ @param mw MainMw object
+ """
+ if event.button == 3:
+ selection = widget.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = mw.sources.get_value(selection_iter, 2)
+ else:
+ return
+ popup_menu = gtk.Menu()
+ actiongroup = gtk.ActionGroup('Popup')
+ actiongroup_list = [('Rename', None, '_Rename', None, None, cb_rename),
+ ('Rename Folder', None, '_Rename Folder', None, None, cb_rename_folder),
+ ('Open in Editor', None, '_Open in Editor', None, None, cb_open_in_editor),
+ ('New Source...', gtk.STOCK_FILE, '_New Source...', None, None, cb_new_source),
+ ('Copy Existing Source To Project...', gtk.STOCK_COPY, '_Copy Existing Source To Project...', None, None, cb_add_copy_source),
+ ('New Folder', gtk.STOCK_DIRECTORY, 'New _Folder', None, None, cb_new_folder),
+ ('Delete', gtk.STOCK_DELETE, '_Delete', '<Control>d', None, cb_delete),
+ ('Delete Folder', gtk.STOCK_DELETE, '_Delete Folder', None, None, cb_delete_folder),]
+
+
+ actiongroup.add_actions(actiongroup_list, mw)
+ mw.popup_uimanager.insert_action_group(actiongroup, 0)
+
+ # Choose Popup Menu
+ if selected_node == mw.project.directory:
+ # Project Folder
+ merge_id = mw.popup_uimanager.add_ui_from_file(directory + '/src/gui/xml/project_popup.xml')
+ popup_menu = mw.popup_uimanager.get_widget('/popup')
+ elif '.' not in selected_node:
+ # Folder
+ merge_id = mw.popup_uimanager.add_ui_from_file(directory + '/src/gui/xml/folder_popup.xml')
+ popup_menu = mw.popup_uimanager.get_widget('/popup')
+ else:
+ # File
+ if selected_node.endswith('.gm'):
+ return
+ merge_id = mw.popup_uimanager.add_ui_from_file(directory + '/src/gui/xml/file_popup.xml')
+ popup_menu = mw.popup_uimanager.get_widget('/popup')
+
+ popup_menu.connect('deactivate', cb_popup_deactivate, merge_id, mw)
+ popup_menu.show()
+ popup_menu.popup(None, None, None, event.button, event.time)
+
+
+def cb_vte(mw):
+ """
+ Event handler for when the embedded terminal is exited.
+ """
+ mw.dependencyloop.kill_thread()
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\nExiting gEDA Manager.\n')
+ write_logs(mw)
+ mw.project.save()
+ save_settings(mw)
+ kill_processes()
+ gtk.main_quit()
+
+
+def cb_exit(menuitem, mw):
+ """!
+ Event handler for 'Exit'.
+ @param menuitem menuitem that threw the event
+ @param data optional user data to pass in
+ """
+ mw.dependencyloop.kill_thread()
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\nExiting gEDA Manager.\n')
+ write_logs(mw)
+ mw.project.save()
+ save_settings(mw)
+ kill_processes()
+ gtk.main_quit()
+
+
+def cb_destroy(event, mw):
+ """!
+ Event handlder when the form is closed in any fashion.
+ @param event event that was thrown
+ """
+ mw.dependencyloop.kill_thread()
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\nExiting gEDA Manager.\n')
+ write_logs(mw)
+ mw.project.save()
+ save_settings(mw)
+ kill_processes()
+ gtk.main_quit()
diff --git a/src/utils/Callbacks.py.~1~ b/src/utils/Callbacks.py.~1~
new file mode 100644
index 0000000..ca4dac9
--- /dev/null
+++ b/src/utils/Callbacks.py.~1~
@@ -0,0 +1,998 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.utils.Callbacks
+#Callbacks for the gEDA Manager
+#@author Newell Jensen
+
+import os, pygtk, gtk, gnomevfs
+pygtk.require('2.0')
+from src.utils.Utils import get_filename_from_filepath
+
+
+######################################################
+# Callback Methods
+######################################################
+
+def cb_show_about_dialog(menuitem, window):
+ """!
+ Event handler for About menu button.
+ @param menuitem about menuitem that threw the event
+ @param window MainWindow object
+ """
+ window.aboutdialog.show()
+ window.aboutdialog.run()
+ window.aboutdialog.hide()
+
+
+def cb_url_geda_wiki(menuitem, data=None):
+ """!
+ Event handler for gEDA Wiki.
+ @param menuitem menuitem that threw the event
+ @param data optional user data to pass in
+ """
+ gnomevfs.url_show('http://geda.seul.org/wiki/')
+
+
+def cb_url_geda_documentation(menuitem, data=None):
+ """!
+ Event handler for gEDA Documentation.
+ @param menuitem menuitem that threw the event
+ @param data optional user data to pass in
+ """
+ gnomevfs.url_show('http://geda.seul.org/wiki/geda:documentation')
+
+
+def cb_url_geda_manager_blog(menuitem, data=None):
+ """!
+ Event handler for gEDA Manager.
+ @param menuitem menuitem that threw the event
+ @param data optional user data to pass in
+ """
+ gnomevfs.url_show('http://www.gempillar.com')
+
+
+def cb_url_geda_manager_api_documentation(menuitem, data=None):
+ """!
+ Event handler for gEDA Manager.
+ @param menuitem menuitem that threw the event
+ @param data optional user data to pass in
+ """
+ gnomevfs.url_show('http://www.gempillar.com/docs/geda-manager')
+
+
+def cb_new_project(menuitem, gedamanager):
+ """!
+ Event handler for 'New Project'.
+ @param menuitem menuitem that threw the event
+ @param gedamanager current gEDAManager instance
+ """
+ gedamanager.project.save()
+ NewProject(self)
+
+
+def cb_open_project(menuitem, window, gedamanager):
+ """!
+ Event handler for 'Open Project'.
+ @param menuitem menuitem that threw the event
+ @param gedamanager current gEDAManager instance
+ """
+ gedamanager.project.save()
+ dialog = gtk.FileChooserDialog('Open...',
+ window,
+ gtk.FILE_CHOOSER_ACTION_OPEN,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+
+ dialog.set_default_response(gtk.RESPONSE_OK)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("Project files (*.gm)")
+ file_filter.add_pattern('*.gm')
+ dialog.add_filter(file_filter)
+
+ response = dialog.run()
+ if response == gtk.RESPONSE_OK:
+ window.set_project(dialog.get_filename())
+ dialog.destroy()
+
+
+def cb_close_project(menuitem, window, gedamanager):
+ """!
+ Event handler for 'Close Project'.
+ @param menuitem menuitem that threw the event
+ @param window MainWindow object
+ @param gedamanager current gEDAManager instance
+ """
+ window.write_logs()
+ gedamanager.project.save()
+ gedamanager.project.close()
+ # clear the processes window
+ window.processes.clear()
+
+
+def cb_project_closed(widget, event, window):
+ """!
+ Event occurs when a Project object is closed
+ @param widget widget that threw the event
+ @param event event that was thrown
+ @param window MainWindow object
+ """
+ window.output_textbuffer.insert(output_textiter, utils.get_time() + ':\n' + 'Project closed.\n')
+ window.set_menu_defaults()
+ window.set_sources_tree_to_project()
+ window.set_dependencies_tree_to_project()
+
+
+def cb_project_opened(widget, event, window):
+ """!
+ Event occurs when a Project object is opened
+ @param widget widget that threw the event
+ @param event event that was thrown
+ @param window MainWindow object
+ """
+ window.output_textbuffer.insert(output_textiter, utils.get_time() + ':\n' + 'Project ' + project.name + ' opened.\n')
+ window.set_menu_defaults()
+ window.set_sources_tree_to_project()
+ window.set_dependencies_tree_to_project()
+
+
+def cb_project_created(widget, event, window):
+ """!
+ Event occurs when a Project object is created
+ @param widget widget that threw the event
+ @param event event that was thrown
+ """
+ window.output_textbuffer.insert(output_textiter, utils.get_time() + ':\nProject ' + project.name + ' created.\n')
+ window.set_menu_defaults()
+ window.set_sources_tree_to_project()
+ window.set_dependencies_tree_to_new_project()
+
+
+def cb_cursor_changed(widget, window):
+ """!
+ Event occurs when the cursor changes in the treeview.
+ @param widget widget that threw the event
+ """
+ selection = window.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ window.processes_tree.set_sensitive(True)
+ selected_node = window.sources.get_value(selection_iter, 2)
+ filename = get_filename_from_filepath(selected_node)
+ if '.' in filename and not filename.endswith(('.gm','.log')):
+ # Logic to call function to find what type of file it is
+ # and then to populate the according tree view
+ ext = filename.split('.')[-1]
+ get_processes_tree(selected_node, ext, None, True)
+ # Update 'Processes: ' for the 'Processes' tree
+ column = window.processes_tree.get_column(0)
+ column.set_title('Processes for: ' + filename)
+ column = window.processes_tree.get_column(2)
+ column.set_title('status')
+ else: # We have the project folder
+ # Clear out the columns
+ column = window.processes_tree.get_column(0)
+ column.set_title('')
+ column = window.processes_tree.get_column(2)
+ column.set_title('')
+ # clear out the processes
+ window.processes.clear()
+ else: # Set the processes to invisible
+ window.processes_tree.set_sensitive(False)
+
+
+
+def cb_row_changed(model, path, iter, gedamanager):
+ """!
+ Event occurs when the columns change in the dependencies treeview.
+ @param model gtk.TreeStore model for the dependencies
+ """
+ # We only want a file to appear once
+ def recurse_model(row_iter, row):
+ try:
+ for new_row in row_iter:
+ if new_row[1] not in files:
+ new_dep_list[row[1]].append(new_row[1])
+ files.append(new_row[1])
+ new_row_iter = new_row.iterchildren()
+ if new_row_iter != None:
+ recurse_model(new_row_iter, new_row)
+ except StopIteration:
+ print 'StopIteraion'
+ except:
+ print 'except:', sys.exc_info()[0]
+
+ files = []
+ new_dep_list = {}
+ for row in model:
+ if row[1] not in files:
+ new_dep_list[row[1]] = []
+ files.append(row[1])
+ row_iter = row.iterchildren()
+ if row_iter != None:
+ recurse_model(row_iter, row)
+ gedamanager.project.dependency_list = new_dep_list
+
+
+def cb_switch_page(notebook, page, page_num, window):
+ if page_num == 1: # Dependencies notebook tab
+ selection = window.sources_tree.get_selection()
+ selection.unselect_all()
+ window.processes.clear()
+ column = window.processes_tree.get_column(0)
+ column.set_title('')
+ column = window.processes_tree.get_column(2)
+ column.set_title('')
+
+
+# TODO -- try to clean up this method
+def get_processes_tree(window, gedamanager, selected_node=None, ext=None, folder=None, clear=None):
+ """!
+ Method to populate the 'Processes' tree view in the gEDA Manager.
+ @param window MainWindow object
+ @param gedamanager current gEDAManager instance
+ @param selected_node selected node in the 'Sources' tree view
+ @param ext filename extension for the currently selected node
+ in the 'Sources' tree view
+ @param folder flag used to let the method know whether or not a
+ folder has been selected
+ @param clear paramater that is used to force a clearing of the
+ processes model
+ """
+ current_directory = os.getcwd()
+ os.chdir(directory)
+ if clear:
+ window.processes.clear()
+ icon = gtk.IconTheme()
+
+ if ext == None and folder != None:
+ selection = window.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = window.sources.get_value(selection_iter, 2)
+
+ # Iterate over the folder to see what types of files they have
+ # and build the tree this way.
+ files = os.listdir(selected_node)
+ extensions = []
+ for f in files:
+ if not f.endswith(('~','-')):
+ ext = f.split('.')[-1]
+ if ext not in extensions:
+ extensions.append(ext)
+ for ext in extensions:
+ # recursively structure the tree
+ if ext in icon_lut:
+ get_processes_tree(window, selected_node, ext, True)
+ else:
+ print 'icon_lut does not contain:', ext
+ return
+
+ if ext == 'sch':
+ simulation = window.processes.append(None, ['Simulate', None, None])
+ create_pcb = window.processes.append(None, ['Create PCB', None, None])
+ create_netlist = window.processes.append(None, ['Create Netlist', None, None])
+ modify_attributes = window.processes.append(None, ['Modify Attributes', None, None])
+ image = icon.load_icon(window.icons.icon_lut['gspiceui'], 22, 0)
+ processes.append(simulation, ['gspiceui', image, None])
+ image = icon.load_icon(window.icons.icon_lut['g2p'], 22, 0)
+ processes.append(create_pcb, ['gsch2pcb workflow', image, None])
+ image = icon.load_icon(window.icons.icon_lut['net'], 22, 0)
+ gnetlist = window.processes.append(create_netlist, ['gnetlist', image, None])
+ for netlist in sorted(netlists):
+ processes.append(gnetlist, [netlist, None, None])
+
+ image = icon.load_icon(window.icons.icon_lut['other'], 22, 0) #refdes -- TODO
+ processes.append(modify_attributes, ['refdes_renum', None, None])
+ image = icon.load_icon(window.icons.icon_lut['other'], 22, 0) #grenum -- TODO
+ processes.append(modify_attributes, ['grenum', None, None])
+ image = icon.load_icon(window.icons.icon_lut['gattrib'], 22, 0)
+ processes.append(modify_attributes, ['gattrib', image, None])
+ elif ext == 'pcb':
+ # TODO -- status image commented out until dependency issues
+ # are taken care of
+ ## status_image = get_status_image(gedamanager, selected_node)
+ ## export = processes.append(None, ['Update PCB (gsch2pcb)', None, status_image])
+ export = processes.append(None, ['Update PCB (gsch2pcb)', None, None])
+ export = processes.append(None, ['Export', None, None])
+ gerber = processes.append(export, ['RS-274X (Gerber) file(s)', None, None])
+ # May need to add for bom1 and bom2
+ bom = processes.append(export, ['Bill of Materials (BOM) file(s)', None, None])
+ nelma = processes.append(export, ['Numerical analysis (Nelma) file(s)', None, None])
+ png = processes.append(export, ['GIF/JPEG/PNG file(s)', None, None])
+ ps = processes.append(export, ['Postscript file(s)', None, None])
+ eps = processes.append(export, ['Encapsulated Postscript file(s)', None, None])
+ _print = processes.append(None, ['Print (lpr)', None, None])
+
+ elif ext == 'gbr':
+ pass # TODO --> any process for this?
+ elif ext == 'sym':
+ check_symbols = processes.append(None, ['Check Symbols', None, None])
+ image = icon.load_icon(window.icons.icon_lut['sym'], 22, 0)
+ processes.append(check_symbols, ['gsymcheck', image, None])
+ elif ext == 'v':
+ compile_source = processes.append(None, ['Compile Verilog', None, None])
+ comsim_source = processes.append(None, ['Compile and Simulate Verilog', None, None])
+ image = icon.load_icon(window.icons.icon_lut['iverilog'], 22, 0)
+ processes.append(compile_source, ['icarus-compile', image, None])
+ processes.append(comsim_source, ['icarus-compile->gtkwave-simulate', image, None])
+ elif ext == 'vvp':
+ simulate = processes.append(None, ['Simulate', None, None])
+ image = icon.load_icon(window.icons.icon_lut['iverilog'], 22, 0)
+ processes.append(simulate, ['iverilog', image, None])
+ elif ext == 'vhd' or ext == 'vhdl':
+ compile_source = processes.append(None, ['Compile VHDL', None, None])
+ comsim_source = processes.append(None, ['Compile and Simulate VHDL', None, None])
+ image = icon.load_icon(window.icons.icon_lut['ghdl'], 22, 0)
+ processes.append(compile_source, ['ghdl-compile', image, None])
+ processes.append(comsim_source, ['ghdl-compile->gtkwave-simulate', image, None])
+ elif ext == 'net':
+ simulation = processes.append(None, ['Simulate', None, None])
+ image = icon.load_icon(window.icons.icon_lut['gspiceui'], 22, 0)
+ processes.append(simulation, ['gspiceui', image, None])
+
+ os.chdir(current_directory)
+
+
+def cb_sources_row_activated(widget, path, view_column, window, gedamanager):
+ """!
+ Event occurs when 'row-activated' signal is emitted or a user double
+ clicks on a treeview row.
+ @param widget widget that threw the event
+ @param path path of the row of the cell to be activated in the gtk.TreeView
+ object
+ @param view_column gtk.TreeViewColumn of the cell to be
+ @param window MainWindow object
+ @param gedamanager current gEDAManager instance
+ activated
+ """
+ selected_node = window.sources[path][2]
+ filename = window.sources[path][1]
+ if '.' in filename: # We have a file
+ ext = filename.split('.')[-1]
+ elif filename in configfiles:
+ ext = 'config'
+ else: # We have a folder
+ ext = 'folder'
+ run_command(gedamanager, selected_node, None, ext)
+
+
+def cb_processes_row_activated(widget, path, view_column, window, gedamanager):
+ """!
+ Event occurs when 'row-activated' signal is emitted or a user double
+ clicks on a treeview row.
+ @param widget widget that threw the event
+ @param path path of the row of the cell to be activated in the gtk.TreeView
+ object
+ @param view_column gtk.TreeViewColumn of the cell to be
+ activated
+ @param gedamanager current gEDAManager instance
+ """
+ selected_node = processes[path][0]
+ selection = window.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ highlighted_source = window.sources.get_value(selection_iter, 2)
+ if highlighted_source not in gedamanager.project.dependency_list:
+ gedamanager.project.dependency_status[highlighted_source] = True
+ gedamanager.project.dependency_list[highlighted_source] = []
+ run_command(gedamanager, selected_node, highlighted_source)
+
+
+def cb_preferences(menuitem, data=None):
+ """!
+ Event occurs when the user opens up the preferences menu.
+ @param menuitem menuitem that threw the event
+ @param data optional user data to pass in
+ """
+ def new_source_cursor_changed(newsources_tree):
+ selection = newsources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ newsource = model.get_value(selection_iter, 1)
+
+ if settings.editor != None:
+ old_editor = settings.editor
+ else:
+ old_editor = None
+
+ def response_to_dialog(entry, dialog, response):
+ dialog.response(response)
+
+ entry = gtk.Entry()
+ if settings.editor != None:
+ entry.set_text(settings.editor)
+ entry.show()
+
+ def cb_filebutton_selection_changed(filechooser, entry):
+ settings.editor = filebutton.get_filename()
+ entry.delete_text(0,-1)
+ entry.set_text(settings.editor)
+
+ dialog = gtk.MessageDialog(self,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_OTHER,
+ gtk.BUTTONS_OK_CANCEL,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>Preference settings:</b>')
+ dialog.set_title('Preferences')
+ hbox = gtk.HBox()
+ hbox.show()
+
+ filebutton = gtk.FileChooserButton('Text Editor')
+ filebutton.show()
+ filebutton.connect('selection-changed',
+ cb_filebutton_selection_changed, entry)
+ filebutton.set_local_only(True)
+ filebutton.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
+ hbox.pack_end(filebutton)
+
+ entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+ hbox.pack_end(entry)
+ label = gtk.Label('Text Editor:')
+ label.show()
+ hbox.pack_end(label)
+
+ dialog.vbox.pack_end(hbox, True, True, 0)
+ dialog.show()
+ dialog.run()
+ if old_editor != settings.editor: # A change was made
+ new_text = settings.editor
+ else:
+ new_text = entry.get_text()
+ dialog.destroy()
+
+ if new_text:
+ settings.editor = new_text
+
+
+def update_file_list(window, index=None, filepath=None):
+ """!
+ Method to update the gEDA Manager's project file list any time
+ the 'Sources' tree view is changed.
+ @param window MainWindow object
+ @param index index -- (0 = add copy source, 1 = delete source,
+ 2 = delete folder, 3 = add a new source, 4 = remove source,
+ 5 = remove folder)
+ @param filepath filepath of the source to copy
+ """
+ selection = window.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = window.sources.get_value(selection_iter, 2)
+ else:
+ return
+ if filepath != None:
+ filename = get_filename_from_filepath(filepath) # Files
+ else:
+ filename = get_filename_from_filepath(selected_node) # Folders
+ icon = gtk.IconTheme()
+ image = icon.load_icon(load_image(filename), 22, 0)
+ path = selected_node + '/' + filename
+
+
+ # Expand the 'Sources' tree view
+ window.sources_tree.expand_all()
+ # Now save the project since the new update file_list is made
+ window.project.save()
+
+
+def cb_delete(menuitem, window):
+ """!
+ Event handler for 'Delete'. This method will delete the file from the
+ filesystem.
+ @param menuitem that threw the event.
+ @param data optional to pass in.
+ """
+ selection = window.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = window.sources.get_value(selection_iter, 2)
+ os.system('rm ' + selected_node)
+ window.output_textbuffer.insert(window.output_textiter, utils.get_time() + ':\nDeleted ' + selected_node + '.\n')
+
+
+def cb_new_source(menuitem, data=None):
+ """!
+ Event occurs when the user wants to add a source to the project
+ @param menuitem menutiem that threw the event
+ @param data optional user data to pass in
+ """
+ def new_source_cursor_changed(newsources_tree):
+ selection = newsources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ newsource = model.get_value(selection_iter, 1)
+ else:
+ newsource = None
+
+ def response_to_dialog(entry, dialog, response):
+ dialog.response(response)
+
+
+ dialog = gtk.MessageDialog(self,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_QUESTION,
+ gtk.BUTTONS_OK_CANCEL,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>Please enter the new file name (extension will be added):</b>')#\n(add extension to override defaults):</b>')
+ entry = gtk.Entry()
+ entry.show()
+ entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+ hbox = gtk.HBox()
+ hbox.show()
+ hbox.pack_end(entry)
+ label = gtk.Label('File name:')
+ label.show()
+ hbox.pack_end(label)
+
+ # Models for the Tree View
+ newsources = gtk.TreeStore(gtk.gdk.Pixbuf, str)
+ # Tree View
+ newsources_tree = gtk.TreeView(newsources)
+ newsources_tree.show()
+ newsources_tree.connect('cursor-changed', new_source_cursor_changed)
+ # column headings
+ newsources_pixbuf = gtk.CellRendererPixbuf()
+ newsources_pixbuf.set_property('xalign', 0)
+ column = gtk.TreeViewColumn(None, newsources_pixbuf, pixbuf=0)
+ newsources_tree.append_column(column)
+ newsources_cell = gtk.CellRendererText()
+ column = gtk.TreeViewColumn('Source Type', newsources_cell, text=1)
+ column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ newsources_tree.append_column(column)
+ # populate the tree view
+ icon = gtk.IconTheme()
+ image = icon.load_icon(utils.icon_lut['pcb'], 22, 0)
+ newsources.append(None, [image, 'PCB (.pcb)'])
+ image = icon.load_icon(utils.icon_lut['sch'], 22, 0)
+ newsources.append(None, [image, 'Schematic (.sch)'])
+ image = icon.load_icon(utils.icon_lut['v'], 22, 0)
+ newsources.append(None, [image, 'Verilog (.v)'])
+ image = icon.load_icon(utils.icon_lut['vhd'], 22, 0)
+ newsources.append(None, [image, 'VHDL (.vhd)'])
+ image = icon.load_icon(utils.icon_lut['sym'], 22, 0)
+ newsources.append(None, [image, 'Symbol (.sym)'])
+
+ # add to the hbox
+ hbox.pack_start(newsources_tree, False, False)
+ dialog.vbox.pack_end(hbox, True, True, 0)
+
+ dialog.show()
+ dialog.run()
+ new_text = entry.get_text()
+ dialog.destroy()
+
+ if new_text and newsource != None:
+ # Get the selected_node for the folder to add to
+ selection = window.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = window.sources.get_value(selection_iter, 2)
+ # Get the type of extension for the program to call
+ if '.' in new_text: # user may have overriden extension
+ return
+ else: # Need to find out what extension from the highlighted node
+ ext = newsource[newsource.find('.')+1:newsource.find(')')]
+ # Make sure a file with the same name doesn't already exist
+ filepath = selected_node + '/' + new_text + '.' + ext
+ filename = new_text + '.' + ext
+ # TODO -- patch up
+ ## # Logic here to add a new source
+ ## selection = gedamanager.sources_tree.get_selection()
+ ## model, selection_iter = selection.get_selected()
+ ## if isinstance(selection_iter, gtk.TreeIter):
+ ## selected_node = gedamanager.sources.get_value(selection_iter, 2)
+ ## else:
+ ## return
+ ## if filepath != None:
+ ## filename = get_filename_from_filepath(filepath) # Files
+ ## else:
+ ## filename = get_filename_from_filepath(selected_node) # Folders
+ ## icon = gtk.IconTheme()
+ ## image = icon.load_icon(load_image(filename), 22, 0)
+ ## path = selected_node + '/' + filename
+
+ ## files = os.listdir(selected_node)
+ ## if filename not in files:
+ ## os.system('touch ' + filepath)
+ ## gedamanager.output_textbuffer.insert(gedamanager.output_textiter, get_time() + ':\n' + 'Added new source:' + filepath + ' to ' + selected_node + '.\n')
+ ## else:
+ ## gedamanager.output_textbuffer.insert(gedamanager.output_textiter, get_time() + ':\n' + filename + ' is already present in the directory: ' + selected_node + '.\n')
+
+
+ utils.update_file_list(1, filepath)
+ utils.run_command(filepath, None, ext)
+ else:
+ dialog = gtk.MessageDialog(self,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_INFO,
+ gtk.BUTTONS_OK,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>Please enter text and/or make sure a file type is selected.</b>')
+ dialog.show()
+ response = dialog.run()
+ dialog.destroy()
+
+
+
+def cb_add_copy_source(menuitem, data=None):
+ """!
+ Event occurs when the user wants to add a source to the project
+ @param menuitem menuitem that threw the event
+ @param data optional user data to pass in
+ """
+ dialog = gtk.FileChooserDialog('Copy Existing Source To Project...',
+ self,
+ gtk.FILE_CHOOSER_ACTION_OPEN,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+
+ dialog.set_default_response(gtk.RESPONSE_OK)
+ file_filters(dialog)
+ response = dialog.run()
+ if response == gtk.RESPONSE_OK:
+ filepath = dialog.get_filename()
+ # TODO -- patch up
+ ## selection = spd.sources_tree.get_selection()
+ ## model, selection_iter = selection.get_selected()
+ ## if isinstance(selection_iter, gtk.TreeIter):
+ ## selected_node = gedamanager.sources.get_value(selection_iter, 2)
+ ## else:
+ ## return
+ ## if filepath != None:
+ ## filename = get_filename_from_filepath(filepath)
+ ## else:
+ ## filename = get_filename_from_filepath(selected_node)
+ ## icon = gtk.IconTheme()
+ ## image = icon.load_icon(load_image(filename), 22, 0)
+ ## path = selected_node + '/' + filename
+
+ ## files = os.listdir(selected_node)
+ ## if filename not in files:
+ ## os.system('cp ' + filepath + ' ' + selected_node)
+ ## gedamanager.output_textbuffer.insert(gedamanager.output_textiter, get_time() + ':\n' + 'Added copy of source:' + filepath + ' to ' + selected_node + '.\n')
+ ## elif filepath == selected_node + '/' + filename:
+ ## gedamanager.output_textbuffer.insert(gedamanager.output_textiter, get_time() + ':\n' + 'Added copy of source:' + filepath + ' to project.\n')
+ ## else:
+ ## gedamanager.output_textbuffer.insert(gedamanager.output_textiter, get_time() + ':\n' + filename + ' is already present in the directory: ' + selected_node + '.\n')
+
+
+ dialog.destroy()
+
+
+
+def cb_new_folder(action):
+ """!
+ Event occurs when the user chooses to add a new folder to the project.
+ @param action gtk.Action object
+ """
+ def response_to_dialog(entry, dialog, response):
+ dialog.response(response)
+
+ selection = window.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = window.sources.get_value(selection_iter, 2)
+ if '.' in selected_node:
+ # This is not a folder
+ # YES, this is a hack and was put in place because
+ # we get some problems if the use right clicks on a node before
+ # it becomes highlighted.
+ return
+ os.chdir(selected_node)
+ dialog = gtk.MessageDialog(self,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_QUESTION,
+ gtk.BUTTONS_OK_CANCEL,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>Please enter new folder name:</b>\nIf the folder name you choose exists\non disk in this directory it will deleted.')
+ entry = gtk.Entry()
+ entry.show()
+ entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+ hbox = gtk.HBox()
+ hbox.show()
+ hbox.pack_end(entry)
+ dialog.vbox.pack_end(hbox, True, True, 0)
+ dialog.show()
+ response = dialog.run()
+ text = entry.get_text()
+ if response == gtk.RESPONSE_OK and text.strip() != '':
+ filepath = selected_node + '/' + text
+
+ def delete_dependency_list_entry(arg, dirname, filenames):
+ """ function to delete the filenames from the dependency_list """
+ for f in filenames:
+ if f in project.dependency_list and list(utils.flatten(project.file_list)).count(f) == 1:
+ del project.dependency_list[f]
+
+ # See if this directory already exists
+ if os.path.exists(filepath): # delete directory recursively
+ os.path.walk(filepath, delete_dependency_list_entry, None)
+ shutil.rmtree(filepath)
+ flag = True
+ i = 0
+ while flag:
+ child_iter = window.sources.iter_nth_child(selection_iter, i)
+ if child_iter != None:
+ child_node = window.sources.get_value(child_iter, 2)
+ if child_node == filepath:
+ flag = window.sources.remove(child_iter)
+ if flag: # break out if flag is true
+ flag = False
+ else:
+ break
+ i = i + 1
+ os.mkdir(filepath)
+ dialog.destroy()
+
+
+
+def cb_delete(menuitem, window):
+ """!
+ Event handler for 'Delete'. This method will delete the file from the
+ filesystem.
+ @param menuitem that threw the event.
+ @param data optional to pass in.
+ """
+ selection = window.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = window.sources.get_value(selection_iter, 2)
+ os.system('rm ' + selected_node)
+ output_textbuffer.insert(output_textiter, utils.get_time() + ':\nDeleted ' + selected_node + '.\n')
+
+
+
+def cb_delete_folder(widget, window):
+ """!
+ Event occurs when the user chooses to delete a folder from the project.
+ This method will delete the folder from the filesystem.
+ @param widget that threw the event.
+ """
+ selection = window.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = window.sources.get_value(selection_iter, 2)
+ exists = os.path.exists(selected_node)
+ if exists: # delete directory recursively
+ os.system('rm -rf ' + selected_node)
+ output_textbuffer.insert(output_textiter, utils.get_time() + ':\nDeleted ' + selected_node + '.\n')
+
+
+
+def cb_open_in_editor(action, window):
+ """!
+ Event occurs when the user wants to open a source file in the editor.
+ @param action gtk.Action object involved with this event
+ """
+ selection = window.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = window.sources.get_value(selection_iter, 2)
+ # Run the command as if the file is a text file
+ utils.run_command(selected_node, None, 'txt')
+
+
+
+def cb_rename_folder(action, window):
+ """!
+ Event handler for renaming a folder.
+ @param action gtk.Action object involved with this event
+ """
+ def response_to_dialog(entry, dialog, response):
+ dialog.response(response)
+
+ selection = window.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ old_path = window.sources.get_value(selection_iter, 2)
+ path = window.sources.get_path(selection_iter)
+
+ dialog = gtk.MessageDialog(self,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_QUESTION,
+ gtk.BUTTONS_OK_CANCEL,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>Please enter the new folder name:\n</b>')
+ entry = gtk.Entry()
+ entry.show()
+ entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+ hbox = gtk.HBox()
+ hbox.show()
+ hbox.pack_end(entry)
+ dialog.vbox.pack_end(hbox, True, True, 0)
+ dialog.show()
+ dialog.run()
+ new_text = entry.get_text()
+ dialog.destroy()
+ new_path = old_path.rpartition('/')[0] + '/' + new_text
+
+ if '.' not in new_text:
+ ## We are going to handle the project folder in cb_rename_folder
+ if old_path == project.directory:
+ # Project Folder
+ os.rename(old_path, new_path)
+ project_file = new_path + '/' + project.name + '.gm'
+ os.remove(project_file)
+ project.directory = new_path
+ project.name = new_text
+ ## project.file_list[0] = new_text
+ ## project.file_list[1][0] = new_text + '.gm'
+ project.save()
+ output_textbuffer.insert(output_textiter, 'Project changed from ' + old_path + ' to ' + new_path + '.\n')
+ else:
+ # Regular folder
+ if os.path.exists(new_path):
+ output_textbuffer.insert(output_textiter, 'Folder already exists with this name. Cannot rename.\n')
+ return
+ os.rename(old_path, new_path)
+
+
+def cb_rename(action):
+ """!
+ Event handler for renaming a file.
+ @param action gtk.Action object involved with this event
+ """
+ def response_to_dialog(entry, dialog, response):
+ dialog.response(response)
+
+ selection = window.sources_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ old_path = window.sources.get_value(selection_iter, 2)
+ path = window.sources.get_path(selection_iter)
+
+ dialog = gtk.MessageDialog(self,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_QUESTION,
+ gtk.BUTTONS_OK_CANCEL,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>Please enter the new name\n(including extension if applicable):</b>')
+ entry = gtk.Entry()
+ entry.show()
+ entry.connect('activate', response_to_dialog, dialog, gtk.RESPONSE_OK)
+ hbox = gtk.HBox()
+ hbox.show()
+ hbox.pack_end(entry)
+ dialog.vbox.pack_end(hbox, True, True, 0)
+ dialog.show()
+ dialog.run()
+ new_text = entry.get_text()
+ dialog.destroy()
+ new_path = old_path.rpartition('/')[0] + '/' + new_text
+
+ if '.' in new_text and '.' in old_path:
+ # File
+ os.rename(old_path, new_path)
+ output_textbuffer.insert(output_textiter, old_path + ' changed to ' + new_path + '.\n')
+ elif not '.' in new_text and not '.' in old_path:
+ # Folder -- so image does not need to be changed
+ if os.path.exists(new_path):
+ output_textbuffer.insert(output_textiter, 'Folder already exists with this name. Cannot rename.\n')
+ return
+ os.rename(old_path, new_path)
+ output_textbuffer.insert(output_textiter, old_path + ' changed to ' + new_path + '.\n')
+
+
+def cb_popup_deactivate(popup_menu, merge_id, window):
+ """!
+ Event occurs when the 'deactivate' signal is thrown from
+ the popup menu.
+ @param popup_menu is the popup_menu.
+ @param merge_id is the merge id from the popup uimanager.
+ """
+ # Remove the ui from the uimanager
+ window.popup_uimanager.remove_ui(merge_id)
+
+
+def cb_button_press(widget, event, window, gedamanager):
+ """!
+ This signal handler will be called when the treeview emits
+ a 'button_press_event' signal.
+ @param widget widget that threw the event
+ @param event event that was thrown
+ @param window MainWindow object
+ @param gedamanager current gEDAManager instance
+ """
+ if event.button == 3:
+ selection = widget.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ selected_node = window.sources.get_value(selection_iter, 2)
+ else:
+ return
+ popup_menu = gtk.Menu()
+ actiongroup = gtk.ActionGroup('Popup')
+ actiongroup_list = [('Rename', None, '_Rename', None, None, cb_rename),
+ ('Rename Folder', None, '_Rename Folder', None, None, cb_rename_folder),
+ ('Open in Editor', None, '_Open in Editor', None, None, cb_open_in_editor),
+ ('New Source...', gtk.STOCK_FILE, '_New Source...', None, None, cb_new_source),
+ ('Copy Existing Source To Project...', gtk.STOCK_COPY, '_Copy Existing Source To Project...', None, None, cb_add_copy_source),
+ ('New Folder', gtk.STOCK_DIRECTORY, 'New _Folder', None, None, cb_new_folder),
+ ('Delete', gtk.STOCK_DELETE, '_Delete', '<Control>d', None, cb_delete),
+ ('Delete Folder', gtk.STOCK_DELETE, '_Delete Folder', None, None, cb_delete_folder),]
+
+
+ actiongroup.add_actions(actiongroup_list)
+ window.popup_uimanager.insert_action_group(actiongroup, 0)
+
+ # Choose Popup Menu
+ if selected_node == gedamanager.project.directory:
+ # Project Folder
+ merge_id = window.popup_uimanager.add_ui_from_file(directory + '/src/gui/xml/project_popup.xml')
+ popup_menu = window.popup_uimanager.get_widget('/popup')
+ elif '.' not in selected_node:
+ # Folder
+ merge_id = window.popup_uimanager.add_ui_from_file(directory + 'src/gui/xml/folder_popup.xml')
+ popup_menu = window.popup_uimanager.get_widget('/popup')
+ else:
+ # File
+ if selected_node.endswith('.gm'):
+ return
+ merge_id = window.popup_uimanager.add_ui_from_file(directory + '/src/gui/xml/file_popup.xml')
+ popup_menu = window.popup_uimanager.get_widget('/popup')
+
+ popup_menu.connect('deactivate', cb_popup_deactivate, merge_id, window)
+ popup_menu.show()
+ popup_menu.popup(None, None, None, event.button, event.time)
+
+
+def cb_vte(self, window, gedamanager):
+ """
+ Event handler for when the embedded terminal is exited.
+ """
+ gedamanager.dependencyloop.kill_thread()
+ window.output_textbuffer.insert(window.output_textiter, get_time() + ':\nExiting gEDA Manager.\n')
+ write_logs()
+ project.save()
+ save_settings()
+ kill_processes()
+ gtk.main_quit()
+
+
+def cb_exit(menuitem, window, gedamanager):
+ """!
+ Event handler for 'Exit'.
+ @param menuitem menuitem that threw the event
+ @param data optional user data to pass in
+ """
+ gedamanager.dependencyloop.kill_thread()
+ window.output_textbuffer.insert(window.output_textiter, get_time() + ':\nExiting gEDA Manager.\n')
+ write_logs()
+ project.save()
+ save_settings()
+ kill_processes()
+ gtk.main_quit()
+
+
+def cb_destroy(event, window, gedamanager):
+ """!
+ Event handlder when the form is closed in any fashion.
+ @param event event that was thrown
+ """
+ gedamanager.dependencyloop.kill_thread()
+ window.output_textbuffer.insert(window.output_textiter, get_time() + ':\nExiting gEDA Manager.\n')
+ write_logs()
+ project.save()
+ save_settings()
+ kill_processes()
+ gtk.main_quit()
diff --git a/src/utils/Decorators.py b/src/utils/Decorators.py
new file mode 100644
index 0000000..3546f34
--- /dev/null
+++ b/src/utils/Decorators.py
@@ -0,0 +1,61 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.utils.Decorators
+#Library file for decorators
+#@author Newell Jensen
+
+import sys, time
+
+
+def exceptions(func):
+ """!
+ Exceptions decorator for functions that are in the Utils or gEDAManager
+ class. Decorator to decorate functions for generic exception handling
+ and logging this to the errors text buffer.
+ @param func function that will be decorated
+ @return func_to_decorate which is the decorated function
+ """
+ def func_to_decorate(*args):
+ """!
+ New function that is returned by exceptions decorator.
+ @param *args arguments that are passed to the the function that
+ is being decorated (func)
+ @return decorated function
+ """
+ f = None
+ for arg in args:
+ if hasattr(arg, 'errors_textbuffer'):
+ try:
+ f = func(*args)
+ except IOError:
+ arg.errors_textbuffer.insert(arg.errors_textiter, time.asctime(time.localtime(time.time())) + ':\nIOError- ' + str(sys.exc_info()) + ' ' + str(func) + '.\n')
+ except OSError:
+ arg.errors_textbuffer.insert(arg.errors_textiter, time.asctime(time.localtime(time.time())) + ':\nOSError- ' + str(sys.exc_info()) + ' ' + str(func) + '.\n')
+ except IndexError:
+ arg.errors_textbuffer.insert(arg.errors_textiter, time.asctime(time.localtime(time.time())) + ':\nIndexError- ' + str(sys.exc_info()) + ' ' + str(func) + '.\n')
+ except TypeError:
+ arg.errors_textbuffer.insert(arg.errors_textiter, time.asctime(time.localtime(time.time())) + ':\nTypeError- ' + str(sys.exc_info()) + ' ' + str(func) + '.\n')
+ except:
+ arg.errors_textbuffer.insert(arg.errors_textiter, time.asctime(time.localtime(time.time())) + ':\nUnexpected error- ' + str(sys.exc_info()) + ' ' + str(func) + '.\n')
+ raise
+ return f
+
+ return func_to_decorate
diff --git a/src/utils/DependencyLoop.py b/src/utils/DependencyLoop.py
new file mode 100644
index 0000000..f2485e9
--- /dev/null
+++ b/src/utils/DependencyLoop.py
@@ -0,0 +1,80 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.utils.DependencyLoop
+#Class to handle dependency loop for the project's sources.
+#@author Newell Jensen
+
+from src.utils.ProcessDependencyEvent import *
+
+
+class DependencyLoop:
+ """
+ Class to handle the dependency loop for the project's sources.
+ This class uses the python module pyinotify which is used to watch for
+ filesystem changes. This is all run in a separate thread from the main
+ execution thread and called as a seperate program in its own process.
+ """
+ def __init__(self, mainwindow):
+ """!
+ Constructor for the DependencyLoop class.
+ This class is component of the gEDAManager class ('has-a' relationship).
+ @param gedamanager current gEDAManager instance
+ """
+ self.mask = IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO
+ self.mw = mainwindow
+ self.watch_manager = WatchManager()
+ self.processdependencyevent = ProcessDependencyEvent(self.mw)
+ self.threaded_notifier = ThreadedNotifier(self.watch_manager, self.processdependencyevent)
+
+ self.threaded_notifier.start()
+ # start watching the project's directory recursively
+ self.wdd = None
+ if self.mw.project.directory != None:
+ self.wdd = self.watch_manager.add_watch(self.mw.project.directory, self.mask, rec=True)
+
+
+ def switch_projects(self):
+ """
+ Method to switch which directory is being watched for events.
+ This method will be called when projects are changed, etc.
+ """
+ # Takes care of subdirectories
+ if self.wdd != None:
+ self.watch_manager.rm_watch(self.wdd.values())
+ # Now add a new watch to the new project
+ if self.mw.project.directory != None:
+ self.wdd = self.watch_manager.add_watch(self.mw.project.directory, self.mask, rec=True)
+
+
+ def update_watch(self):
+ """
+ Method to update the directory that is already under watch.
+ """
+ self.wdd = self.watch_manager.add_watch(self.mw.project.directory, self.mask, rec=True)
+
+
+ def kill_thread(self):
+ """
+ Method to kill the DependencyLoop thread when gEDAManager exits.
+ """
+ self.threaded_notifier.stop()
+
+
diff --git a/src/utils/DependencyLoop.py.~1~ b/src/utils/DependencyLoop.py.~1~
new file mode 100644
index 0000000..66913f1
--- /dev/null
+++ b/src/utils/DependencyLoop.py.~1~
@@ -0,0 +1,79 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.utils.DependencyLoop
+#Class to handle dependency loop for the project's sources.
+#@author Newell Jensen
+
+import gtk, pygtk
+pygtk.require('2.0')
+from pyinotify import *
+from src.utils.ProcessDependencyEvent import *
+
+
+class DependencyLoop:
+ """
+ Class to handle the dependency loop for the project's sources.
+ This class uses the python module pyinotify which is used to watch for
+ filesystem changes. This is all run in a separate thread from the main
+ execution thread and called as a seperate program in its own process.
+ """
+ def __init__(self, gedamanager):
+ """!
+ Constructor for the DependencyLoop class.
+ This class is component of the gEDAManager class ('has-a' relationship).
+ @param gedamanager current gEDAManager instance
+ """
+ # Things to do: (we can get all the info from the gedamanager object
+ # Start the thread with the project's directory
+ self.g = gedamanager
+ self.watch_manager = WatchManager()
+ self.processdependencyevent = ProcessDependencyEvent(self.g)
+ self.threaded_notifier = ThreadedNotifier(self.watch_manager, self.processdependencyevent)
+
+ self.threaded_notifier.start()
+ # start watching the project's directory recursively
+ self.wdd = None
+ mask = IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO
+ if self.g.project.directory != None:
+ self.wdd = self.watch_manager.add_watch(self.g.project.directory, mask, rec=True)
+
+
+ def switch_projects(self):
+ """
+ Method to switch which directory is being watched for events.
+ This method will be called when projects are changed, etc.
+ """
+ # Takes care of subdirectories
+ if self.wdd != None:
+ self.watch_manager.rm_watch(self.wdd.values())
+ # Now add a new watch to the new project
+ mask = IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO
+ if self.g.project.directory != None:
+ self.wdd = self.watch_manager.add_watch(self.g.project.directory, mask, rec=True)
+
+
+ def kill_thread(self):
+ """
+ Method to kill the DependencyLoop thread when gEDAManager exits.
+ """
+ self.threaded_notifier.stop()
+
+
diff --git a/src/utils/Helpers.py b/src/utils/Helpers.py
new file mode 100644
index 0000000..ff5938e
--- /dev/null
+++ b/src/utils/Helpers.py
@@ -0,0 +1,650 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.utils.Utils
+#Utility class for the gEDA Manager
+#@author Newell Jensen
+
+import gtk, pygtk, os, time
+pygtk.require('2.0')
+from subprocess import *
+from src.gui.Gsch2pcb import Gsch2pcb
+
+
+directory = os.getcwd()
+tools = {'sch': None, 'pcb': None, 'gerbv': None, 'gattrib': None, 'editor': None}
+configfiles = ['gschemrc','.gschemrc','gafrc','.gafrc','gnetlistrc','.gnetlistrc','gattribrc','.gattribrc','attribs','.attribs']
+netlists = ['bom2','calay','mathematica','vipec','geda','systemc','allegro','redac','drc2','cascade','pads','bae','pcbpins','vams','drc','gsch2pcb','partslist2','partslist3','partslist-common','gossip','maxascii','PCB','vhdl','tango','spice-sdb','partstlist1','PCBboard','switchcap','osmond','spice','verilog','bom','eagle','protelII','futurenet2']
+
+def not_implemented(mw):
+ """
+ Method to let the user know that the selected feature is not
+ implemented yet.
+ """
+ dialog = gtk.MessageDialog(mw,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_INFO,
+ gtk.BUTTONS_OK,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>The selected feature is currently not implemented.\nUnder construction.</b>')
+ dialog.show()
+ response = dialog.run()
+ dialog.destroy()
+
+
+def get_time():
+ """ Method returns a string of the current time. """
+ return time.asctime(time.localtime(time.time()))
+
+
+def get_filename_from_filepath(path):
+ """!
+ Method to return the node name from the path.
+ @param path path to the node
+ @return filename of the node without an extension
+ """
+ if '/' in path:
+ return path.split('/')[-1]
+ else:
+ return ''
+
+
+def set_menu_defaults(mw):
+ """
+ Method to coordiante which methods should be called to handle
+ the sensitivity of the menu items.
+ """
+ # Project
+ if mw.project.name == None or mw.project.name == mw.no_project_name:
+ set_no_project_default(mw)
+ else:
+ set_project_default(mw)
+
+
+def set_no_project_default(mw):
+ """
+ Method to set the default sensitivity when no project is loaded.
+ """
+ # File Menu
+ mw.project.name = mw.no_project_name
+ mw.sources_tree.set_property('headers-visible', True)
+ column = mw.sources_tree.get_column(0)
+ column.set_title(mw.project.name)
+ save_project_as_menuitem = mw.menu_uimanager.get_widget('/MenuBar/Project/Save Project As...')
+ close_project_menuitem = mw.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+ close_project_menuitem.set_sensitive(False)
+
+
+def set_project_default(mw):
+ """
+ Method to set the default sensitivity when a project is loaded.
+ """
+ # File Menu
+ mw.sources_tree.set_property('headers-visible', False)
+ save_project_as_menuitem = mw.menu_uimanager.get_widget('/MenuBar/Project/Save Project As...')
+ close_project_menuitem = mw.menu_uimanager.get_widget('/MenuBar/Project/Close Project')
+ close_project_menuitem.set_sensitive(True)
+
+
+def set_project(mw, path):
+ """!
+ Method to set current project to the one on path.
+ @param path path for project to open.
+ """
+ # Save current project
+ if not mw.project.clean:
+ mw.project.save()
+ mw.project.open(path)
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\n' + 'Project set to ' + mw.project.name + '\n')
+ mw.dependencyloop.switch_projects()
+
+
+def set_sources_tree_to_project(mw):
+ """ Method to set the tree to current project object. """
+ mw.sources.clear()
+ if mw.project.name != None:
+ load_sources_tree(mw)
+ mw.sources_tree.expand_all()
+
+
+def set_dependencies_tree_to_project(mw):
+ """ Method to set the tree to current project object. """
+ mw.dependencies.clear()
+ if mw.project.dependency_list != None:
+ load_dependencies_tree(mw)
+ mw.dependencies_tree.expand_all()
+
+
+def set_dependencies_tree_to_new_project(mw):
+ """ Method to set the tree to newly created project object. """
+ #mw.dependencyloop.switch_projects()
+ mw.dependencies.clear()
+ # Parent Folder
+ project_path = mw.project.directory + '/' + mw.project.name
+ project_file_path = project_path + '.gm'
+ output_file_path = mw.project.directory + '/output.log'
+ error_file_path = mw.project.directory + '/error.log'
+
+
+def load_sources_tree(mw):
+ """
+ Method to the load the 'Sources' TreeView from the
+ directory structure of the project.
+ """
+ if mw.sources != None:
+ # Clear out the sources first
+ mw.sources.clear()
+ # Start adding data to the Model
+ if isinstance(mw.project.directory, str):
+ if os.path.exists(mw.project.directory):
+ os.chdir(mw.project.directory)
+ node = None
+ dictionary = {}
+ icon = gtk.IconTheme() # The icon used throughout the function
+ for root, dirs, files in os.walk(mw.project.directory):
+ if root == mw.project.directory:
+ image = icon.load_icon(mw.icons.icon_lut['project'], 22, 0)
+ else:
+ image = icon.load_icon(mw.icons.icon_lut['folder'], 22, 0)
+
+ folder = root.split('/')[-1]
+ try:
+ node = mw.sources.append(dictionary[root], [image, folder, root])
+ except KeyError:
+ node = mw.sources.append(None, [image, folder, root])
+ for f in [name for dec,name in sorted((os.path.splitext(f)[1][1:],f) for f in files)]: # List expression sorts by file extension
+ if not f.endswith(('~','-','#')):
+ image = icon.load_icon(mw.icons.load_image(f), 22, 0)
+ mw.sources.append(node, [image, f, os.path.join(root, f)])
+ for d in dirs:
+ dictionary[os.path.join(root, d)] = node
+
+ mw.sources_tree.expand_all()
+
+
+def load_dependencies_tree(mw):
+ """!
+ Method to the load the dependencies tree
+ """
+ # Need to add checking for whether or not the filesystem still
+ # has the files before appending them to mw.dependencies
+
+ # Either this or have a function that I call before this one that
+ # straightens it all out by going over the dependency_list and making
+ # sure that these files are the correct ones and if not it can call
+ # the functions remove/add/update_dependency() functions
+ def recurse_dependencies(dep_list, parent):
+ for value in dep_list:
+ filename = get_filename_from_filepath(value)
+ n_parent = mw.dependenices.append(parent, [filename, value])
+ # recurse
+ if mw.project.dependency_list[value] != []:
+ recurse_dependencies(mw.project.dependency_list[value], n_parent)
+
+ if mw.dependencies != None:
+ mw.dependencies.clear()
+ for key, value in mw.project.dependency_list.iteritems():
+ filename = get_filename_from_filepath(key)
+ n_parent = mw.dependencies.append(None, [filename, key])
+ # recurse
+ if mw.project.dependency_list[key] != []:
+ recurse_dependencies(value, n_parent)
+
+
+def update_dependency(mw, pathname, recurse=False):
+ # First, make sure that the file is already in the dependencies
+ if mw.project.dependency_status != None:
+ try:
+ if not recurse:
+ mw.project.dependency_status[pathname] = True
+ else:
+ mw.project.dependency_status[pathname] = False
+ # recurse over the dependency_list
+ if mw.project.dependency_list != None:
+ for value in mw.project.dependency_list[pathname]:
+ mw.update_dependency(value, True)
+ except KeyError:
+ print 'KeyError_update'
+ finally:
+ mw.project.save()
+ load_dependencies_tree(mw)
+
+
+def add_dependency(mw, pathname):
+ print 'in add_dependency'
+ try:
+ if mw.project.dependency_list != None:
+ mw.project.dependency_list[pathname] = []
+ if mw.project.dependency_status != None:
+ mw.project.dependency_status[pathname] = True
+ except KeyError:
+ print 'KeyError_add'
+ finally:
+ mw.project.save()
+ load_dependencies_tree(mw)
+
+
+def remove_dependency(mw, pathname, recurse=False):
+ # First, make sure that the file is already in the dependencies
+ if mw.project.dependency_status != None:
+ if pathname in mw.project.dependency_status:
+ try:
+ # iterate over the dependencies and flatten
+ for value in mw.project.dependency_list[pathname]:
+ mw.remove_dependency(value, True)
+ mw.project.dependency_list[pathname] = []
+ except KeyError:
+ pass
+ #print 'KeyError_remove'
+ finally:
+ # Commented out until dependencies are figured out
+ ## if not recurse:
+ ## del mw.project.dependency_status[pathname]
+ ## del mw.project.dependency_list[pathname]
+ ## else:
+ ## mw.project.dependency_status[pathname] = False
+ mw.project.save()
+ load_dependencies_tree(mw)
+
+
+def get_processes_selected_node(mw):
+ """!
+ Method to get the selected node in the 'Processes' treeview.
+ @return path of the selected node
+ """
+ selection = mw.processes_tree.get_selection()
+ model, selection_iter = selection.get_selected()
+ if isinstance(selection_iter, gtk.TreeIter):
+ return mw.processes.get_value(selection_iter, 2)
+ else:
+ return None
+
+
+def file_filters(mw, dialog):
+ """!
+ Method to abstract some redundant code that is used in the message
+ dialog boxes.
+ @param dialog gtk.FileChooserDialog object
+ """
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("All files")
+ file_filter.add_pattern('*')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("schematics (.sch)")
+ file_filter.add_pattern('*.sch')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("symbols (.sym)")
+ file_filter.add_pattern('*.sym')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("pcb (.pcb)")
+ file_filter.add_pattern('*.pcb')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("verilog (.v)")
+ file_filter.add_pattern('*.v')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("vhdl (.vhd)")
+ file_filter.add_pattern('*.vhd')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("bom (.bom)")
+ file_filter.add_pattern('*.bom')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("drc (.drc)")
+ file_filter.add_pattern('*.drc')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("gerber (.gbr)")
+ file_filter.add_pattern('*.gbr')
+ dialog.add_filter(file_filter)
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name("spice (.spice)")
+ file_filter.add_pattern('*.spice')
+ dialog.add_filter(file_filter)
+
+
+def set_project(path, mw):
+ """!
+ Method to set current project to the one on path.
+ @param path path for project to open.
+ """
+ # Save current project
+ if not mw.project.clean:
+ print 'mw: set_project is implemented'
+ mw.project.save()
+ mw.project.open(path)
+ mw.sources_tree.set_property('headers-visible', True)
+ column = mw.sources_tree.get_column(0)
+ column.set_title('Project: ' + mw.project.name)
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ':\n' + 'Project set to ' + mw.project.name + '\n')
+ mw.dependencyloop.switch_projects()
+
+
+def save_settings(mw):
+ """ Method to save current settings to .gmrc file. """
+
+ if mw.project.directory and mw.project.name:
+ mw.settings.project = mw.project.directory + '/' + mw.project.name + '.gm'
+ else:
+ mw.settings.project = None
+ mw.settings.create_config_file()
+
+
+def kill_processes(mw):
+ """
+ Method to kill all the open processes if there are still any
+ open when the gEDAManager is closed.
+ """
+ for tool, value in tools.iteritems():
+ if value != None and not isinstance(value, str): # kill the process
+ try:
+ os.kill(value.pid, signal.SIGKILL)
+ except OSError:
+ print 'OSError:', sys.exc_info()[0]
+
+
+def flatten(lst):
+ """!
+ Method to flatten a nested list with tuple or list elements.
+ @param lst nested list to flatten
+ """
+ for elem in lst:
+ if type(elem) in (tuple, list):
+ for i in flatten(elem):
+ yield i
+ else:
+ yield elem
+
+
+def is_filename_in_dependencies(mw, filename, delete=False):
+ """!
+ Method to determine if the given filename is in the project's
+ dependencies.
+ @param mw current mw instance
+ @param filename name of the file under investigation
+ @return True or False
+ """
+ # TODO -- this still needs fixing for the delete part
+ # Need to iterate through to see if the filename is in the tree
+ if filename != None:
+ for row in mw.dependencies:
+ if row[0] == filename:
+ if delete:
+ pass
+ #del mw.dependencies[row],
+ return True
+ row_iter = row.iterchildren()
+ if row_iter != None: # We have children in this row
+ child_list = child_recurse(row_iter, 0)
+ if child_list != None:
+ child_list = [x for x in child_list if x != None]
+ for x in child_list:
+ if x == filename:
+ if delete:
+ pass
+ #del mw.dependencies[x]
+ #mw.dependencies.remove(iter_remove)
+ return True
+ return False
+
+
+def child_recurse(row_iter, index):
+ """!
+ Method to iterate recursively over child nodes.
+ @param row_iter gtk.TreeModelRowIter object
+ @param index index of the row to add to the returned list
+ @return list of child nodes
+ """
+ child_list = []
+ while True:
+ try:
+ child_row = row_iter.next()
+ child_list.append(child_row[index])
+ child_row_iter = child_row.iterchildren()
+ if child_row_iter != None:
+ child_list.append(child_recurse(child_row_iter, index))
+ except StopIteration:
+ break
+ for x in child_list:
+ if x == None:
+ child_list.remove(x)
+ if child_list != []:
+ return child_list
+
+
+def run_command(mw, filepath, highlighted_source=None, ext=None):
+ """!
+ Method to run commands for 'Processes' and 'Sources'.
+ @param mw current mw instance
+ @param filepath selected 'Sources' or 'Processes' node
+ @param highlighted_source highlighted 'Sources' node that
+ is being used for the current process
+ @param ext extension of the selected file
+ """
+ files = ['net','log','bom','bom1','bom2','v','vhd','gm','txt','cmd']
+ # Sources
+ if ext != None:
+ os.chdir(filepath.rpartition('/')[0])
+ if ext == 'sch' or ext == 'sym':
+ if tools['sch'] == None or tools['sch'].poll() == 0:
+ tools['sch'] = Popen(['gschem', filepath])
+ elif tools['sch'].poll() == None: # Process is still running
+ pass
+ elif ext == 'pcb':
+ if tools['pcb'] == None or tools['pcb'].poll() == 0:
+ tools['pcb'] = Popen(['pcb', filepath])
+ elif tools['pcb'].poll() == None: # Process is still running
+ pass
+ elif ext == 'gbr':
+ if tools['gerbv'] == None or tools['gerbv'].poll() == 0:
+ tools['gerbv'] = Popen(['gerbv', filepath])
+ elif tools['gerbv'].poll() == None: # Process is still running
+ pass
+ elif (ext in files or ext in configfiles):
+ if mw.settings.editor == None:
+ dialog = gtk.MessageDialog(mw.window,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_INFO,
+ gtk.BUTTONS_OK,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>Please go to Edit->Preferences and choose a default text editor.</b>')
+ dialog.show()
+ response = dialog.run()
+ dialog.destroy()
+ else:
+ Popen([mw.settings.editor, filepath])
+
+ else: # Processes
+ print 'highlighted_source:',highlighted_source
+ os.chdir(highlighted_source.rpartition('/')[0])
+ program = filepath
+ print 'program:',program
+ # Netlists
+ if program in netlists: # use gnetlist
+ subproc = Popen(['gnetlist', '-v', '-g', program, highlighted_source], stdout=PIPE)
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ' and output from ' + program + ':\n' + subproc.communicate()[0] + '\n')
+ elif program == 'gspiceui':
+ print 'in'
+ subproc = Popen([program, highlighted_source], stdout=PIPE)
+ elif program == 'ghdl-compile':
+ # TODO
+ not_implemented(mw)
+ elif program == 'ghdl-compile->gtkwave-simulate':
+ # TODO
+ not_implemented(mw)
+ pass
+ elif program == 'icarus-compile':
+ subproc = Popen(['iverilog', '-v', '-o', get_filename_from_filepath(highlighted_source).rsplit('.')[0] + '.vvp', highlighted_source], stdout=PIPE)
+ elif program == 'icarus-compile->gtkwave-simulate':
+ # TODO
+ not_implemented(mw)
+ pass
+ elif program == 'gattrib':
+ if tools['gattrib'] == None or tools['gattrib'].poll() == 0:
+ tools['gattrib'] = Popen([program, highlighted_source], stdout=PIPE)
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ' and output from ' + program + ':\n' + tools['gattrib'].communicate()[0] + '.\n')
+ elif tools['gattrib'].poll() == None: # Process is still running
+ pass
+ elif program == 'gsymcheck':
+ arg = '-v ' + highlighted_source
+ subproc = Popen([program, arg], stdout=PIPE)
+ mw.output_textbuffer.insert(mw.output_textiter, get_time() + ' and output from ' + program + ':\n' + subproc.communicate()[0] + '.\n')
+ elif program == 'gsch2pcb workflow':
+ gsch2pcb = Gsch2pcb(mw, highlighted_source)
+ elif program == 'Update PCB (gsch2pcb)':
+ not_implemented(mw)
+ # The stuff below is commented out until the dependency issues
+ # are solved
+ ## # Only run if the highlighted_souce is outdated
+ ## if not mw.project.dependency_status[highlighted_source]:
+ ## files_before = os.listdir(highlighted_source.rpartition('/')[0])
+ ## schematics_list = []
+ ## # TODO
+ ## if schematics_list:
+ ## schematics = ''
+ ## for sch in schematics_list:
+ ## schematics += sch + ' '
+
+ ## name = filename.split('.')[0]
+ ## subproc = Popen(['gsch2pcb', '-v','-v','-o',name,schematics]).wait()
+ ## files_after = os.listdir(highlighted_source.rpartition('/')[0])
+ ## files = [x for x in files_after if x not in files_before]
+ ## # Add any new files to the sources tree view if any
+ ## if files:
+ ## icon = gtk.IconTheme()
+ ## selection = mw.sources_tree.get_selection()
+ ## model, selection_iter = selection.get_selected()
+ ## if isinstance(selection_iter, gtk.TreeIter):
+ ## parent_iter = mw.sources.iter_parent(selection_iter)
+ ## wanted = ['pcb','new.pcb','net']
+ ## new_files = []
+ ## new_files.append(True)
+ ## for f in files:
+ ## if f.endswith('new.pcb'):
+ ## ext = 'new.pcb'
+ ## else:
+ ## ext = f.split('.')[-1]
+ ## if ext in wanted:
+ ## filepath = directory + '/' + f
+ ## image = icon.load_icon(icon_lut[ext], 22, 0)
+ ## # Need to see if there are any new files
+ ## new_files.append(f)
+ ## print 'new_files:',new_files
+ ## else:
+ ## print 'no new files'
+
+ ## else:
+ ## not_implemented(mw)
+ ## ## TODO I will need to change the below since 'program' may
+ ## ## not be an actual program
+ ## ## subproc = Popen([program, highlighted_source])
+ ## mw.processes_tree.set_sensitive(False)
+
+
+def write_logs(mw):
+ """
+ Method to write out the error and output logs with what is in
+ the textbuffers.
+ """
+ startiter, enditer = mw.output_textbuffer.get_bounds()
+ output = mw.output_textbuffer.get_text(startiter, enditer)
+ os.chdir(mw.project.directory)
+ f = file('output.log', 'a')
+ f.writelines(output)
+ f.close()
+
+ startiter, enditer = mw.errors_textbuffer.get_bounds()
+ errors = mw.errors_textbuffer.get_text(startiter, enditer)
+ os.chdir(mw.project.directory)
+ f = file('error.log', 'a')
+ f.writelines(errors)
+ f.close()
+
+
+def kill_processes():
+ """
+ Method to kill all the open processes if there are still any
+ open when the gEDAManager is closed.
+ """
+ for tool, value in tools.iteritems():
+ if value != None and not isinstance(value, str): # kill the process
+ try:
+ os.kill(value.pid, signal.SIGKILL)
+ except OSError:
+ print 'OSError:', sys.exc_info()[0]
+
+
+ ## def update_dependency_list(mw, filename, flag=False):
+ ## """!
+ ## Method to update the dependencies for filename.
+ ## @param filename file that will have its dependencies updated
+ ## or list of filenames that will have its dependencies updated
+ ## @param flag sets status of filename
+ ## """
+ ## if isinstance(filename, list):
+ ## for f in filename:
+ ## mw.project.dependency_list[f][0] = flag
+ ## for x in mw.project.dependency_list[f][1:]:
+ ## update_dependency_list(mw, x, False)
+ ## else:
+ ## # We just need to create a new list and set that as the value
+ ## mw.project.dependency_list[filename][0] = flag
+ ## for x in mw.project.dependency_list[filename][1:]:
+ ## # recurse over files and make out of date
+ ## update_dependency_list(mw, x, False)
+
+
+ ## def add_to_dependency_list(mw, filename):
+ ## """!
+ ## Method to add a file to the project's dependency_list.
+ ## @param filename file to add to project.dependency_list
+ ## """
+ ## # add file to the dependency_list
+ ## if filename not in mw.project.dependency_list:
+ ## mw.project.dependency_list[filename] = [True, [], []]
+
+ ## def get_status_image(mw, highlighted_source):
+ ## """!
+ ## Method to get the status image for the process.
+ ## @param mw current mw instance
+ ## @param highlighted_source currently selected node in the 'Sources' tree view.
+ ## @return icon from the icon_lut structure
+ ## """
+ ## icon = gtk.IconTheme()
+ ## if highlighted_source in mw.project.dependency_status:
+ ## if mw.project.dependency_status[highlighted_source] != None:
+ ## if mw.project.dependency_status[highlighted_source]:
+ ## return icon.load_icon(icon_lut['updated'], 22, 0)
+ ## else:
+ ## return icon.load_icon(icon_lut['outdated'], 22, 0)
diff --git a/src/utils/Helpers.py.~1~ b/src/utils/Helpers.py.~1~
new file mode 100644
index 0000000..fc301a5
--- /dev/null
+++ b/src/utils/Helpers.py.~1~
@@ -0,0 +1,385 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.utils.Utils
+#Utility class for the gEDA Manager
+#@author Newell Jensen
+
+import gtk, pygtk, os, time
+pygtk.require('2.0')
+from src.gui.Gsch2pcb import Gsch2pcb
+from src.utils.Callbacks import *
+from subprocess import *
+
+directory = os.getcwd()
+tools = {'sch': None, 'pcb': None, 'gerbv': None, 'gattrib': None, 'editor': None}
+configfiles = ['gschemrc','.gschemrc','gafrc','.gafrc','gnetlistrc','.gnetlistrc','gattribrc','.gattribrc','attribs','.attribs']
+netlists = ['bom2','calay','mathematica','vipec','geda','systemc','allegro','redac','drc2','cascade','pads','bae','pcbpins','vams','drc','gsch2pcb','partslist2','partslist3','partslist-common','gossip','maxascii','PCB','vhdl','tango','spice-sdb','partstlist1','PCBboard','switchcap','osmond','spice','verilog','bom','eagle','protelII','futurenet2']
+
+def not_implemented(gedamanager):
+ """
+ Method to let the user know that the selected feature is not
+ implemented yet.
+ """
+ dialog = gtk.MessageDialog(gedamanager.window,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_INFO,
+ gtk.BUTTONS_OK,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>The selected feature is currently not implemented.\nUnder construction.</b>')
+ dialog.show()
+ response = dialog.run()
+ dialog.destroy()
+
+
+def get_time():
+ """ Method returns a string of the current time. """
+ return time.asctime(time.localtime(time.time()))
+
+
+def get_filename_from_filepath(path):
+ """!
+ Method to return the node name from the path.
+ @param path path to the node
+ @return filename of the node without an extension
+ """
+ if '/' in path:
+ return path.split('/')[-1]
+ else:
+ return ''
+
+
+def set_project(path):
+ """!
+ Method to set current project to the one on path.
+ @param path path for project to open.
+ """
+ # Save current project
+ if not project.clean:
+ print 'gedamanager: set_project is implemented'
+ project.save()
+ project.open(path)
+ sources_tree.set_property('headers-visible', True)
+ column = sources_tree.get_column(0)
+ column.set_title('Project: ' + project.name)
+ output_textbuffer.insert(output_textiter, utils.get_time() + ':\n' + 'Project set to ' + project.name + '\n')
+ dependencyloop.switch_projects()
+
+
+def save_settings(self):
+ """ Method to save current settings to .gmrc file. """
+
+ if project.directory and project.name:
+ settings.project = project.directory + '/' + project.name + '.gm'
+ else:
+ settings.project = None
+ settings.create_config_file()
+
+
+def kill_processes(self):
+ """
+ Method to kill all the open processes if there are still any
+ open when the gEDAManager is closed.
+ """
+ for tool, value in tools.iteritems():
+ if value != None and not isinstance(value, str): # kill the process
+ try:
+ os.kill(value.pid, signal.SIGKILL)
+ except OSError:
+ print 'OSError:', sys.exc_info()[0]
+
+
+def flatten(lst):
+ """!
+ Method to flatten a nested list with tuple or list elements.
+ @param lst nested list to flatten
+ """
+ for elem in lst:
+ if type(elem) in (tuple, list):
+ for i in flatten(elem):
+ yield i
+ else:
+ yield elem
+
+
+def is_filename_in_dependencies(gedamanager, filename, delete=False):
+ """!
+ Method to determine if the given filename is in the project's
+ dependencies.
+ @param gedamanager current gEDAManager instance
+ @param filename name of the file under investigation
+ @return True or False
+ """
+ # TODO -- this still needs fixing for the delete part
+ # Need to iterate through to see if the filename is in the tree
+ if filename != None:
+ for row in gedamanager.dependencies:
+ if row[0] == filename:
+ if delete:
+ pass
+ #del gedamanager.dependencies[row],
+ return True
+ row_iter = row.iterchildren()
+ if row_iter != None: # We have children in this row
+ child_list = child_recurse(row_iter, 0)
+ if child_list != None:
+ child_list = [x for x in child_list if x != None]
+ for x in child_list:
+ if x == filename:
+ if delete:
+ pass
+ #del gedamanager.dependencies[x]
+ #gedamanager.dependencies.remove(iter_remove)
+ return True
+ return False
+
+
+def child_recurse(row_iter, index):
+ """!
+ Method to iterate recursively over child nodes.
+ @param row_iter gtk.TreeModelRowIter object
+ @param index index of the row to add to the returned list
+ @return list of child nodes
+ """
+ child_list = []
+ while True:
+ try:
+ child_row = row_iter.next()
+ child_list.append(child_row[index])
+ child_row_iter = child_row.iterchildren()
+ if child_row_iter != None:
+ child_list.append(child_recurse(child_row_iter, index))
+ except StopIteration:
+ break
+ for x in child_list:
+ if x == None:
+ child_list.remove(x)
+ if child_list != []:
+ return child_list
+
+
+def run_command(gedamanager, filepath, highlighted_source=None, ext=None):
+ """!
+ Method to run commands for 'Processes' and 'Sources'.
+ @param gedamanager current gEDAManager instance
+ @param filepath selected 'Sources' or 'Processes' node
+ @param highlighted_source highlighted 'Sources' node that
+ is being used for the current process
+ @param ext extension of the selected file
+ """
+ files = ['net','log','bom','bom1','bom2','v','vhd','gm','txt','cmd']
+ # Sources
+ if ext != None:
+ os.chdir(filepath.rpartition('/')[0])
+ if ext == 'sch' or ext == 'sym':
+ if tools['sch'] == None or tools['sch'].poll() == 0:
+ tools['sch'] = Popen(['gschem', filepath])
+ elif tools['sch'].poll() == None: # Process is still running
+ pass
+ elif ext == 'pcb':
+ if tools['pcb'] == None or tools['pcb'].poll() == 0:
+ tools['pcb'] = Popen(['pcb', filepath])
+ elif tools['pcb'].poll() == None: # Process is still running
+ pass
+ elif ext == 'gbr':
+ if tools['gerbv'] == None or tools['gerbv'].poll() == 0:
+ tools['gerbv'] = Popen(['gerbv', filepath])
+ elif tools['gerbv'].poll() == None: # Process is still running
+ pass
+ elif (ext in files or ext in configfiles):
+ if gedamanager.settings.editor == None:
+ dialog = gtk.MessageDialog(gedamanager.window,
+ (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_INFO,
+ gtk.BUTTONS_OK,
+ gtk.STOCK_DIRECTORY)
+ dialog.set_markup('<b>Please go to Edit->Preferences and choose a default text editor.</b>')
+ dialog.show()
+ response = dialog.run()
+ dialog.destroy()
+ else:
+ Popen([gedamanager.settings.editor, filepath])
+
+ else: # Processes
+ os.chdir(highlighted_source.rpartition('/')[0])
+ program = filepath
+ print 'program:',program
+ # Netlists
+ if program in netlists: # use gnetlist
+ subproc = Popen(['gnetlist', '-v', '-g', program, highlighted_source], stdout=PIPE)
+ gedamanager.window.teo.output_textbuffer.insert(gedamanager.window.teo.output_textiter, get_time() + ' and output from ' + program + ':\n' + subproc.communicate()[0] + '\n')
+ elif program == 'gspiceui':
+ print 'in'
+ subproc = Popen([program, highlighted_source], stdout=PIPE)
+ elif program == 'ghdl-compile':
+ # TODO
+ not_implemented(gedamanager)
+ elif program == 'ghdl-compile->gtkwave-simulate':
+ # TODO
+ not_implemented(gedamanager)
+ pass
+ elif program == 'icarus-compile':
+ subproc = Popen(['iverilog', '-v', '-o', get_filename_from_filepath(highlighted_source).rsplit('.')[0] + '.vvp', highlighted_source], stdout=PIPE)
+ elif program == 'icarus-compile->gtkwave-simulate':
+ # TODO
+ not_implemented(gedamanager)
+ pass
+ elif program == 'gattrib':
+ if tools['gattrib'] == None or tools['gattrib'].poll() == 0:
+ tools['gattrib'] = Popen([program, highlighted_source], stdout=PIPE)
+ gedamanager.window.teo.output_textbuffer.insert(gedamanager.window.teo.output_textiter, get_time() + ' and output from ' + program + ':\n' + tools['gattrib'].communicate()[0] + '.\n')
+ elif tools['gattrib'].poll() == None: # Process is still running
+ pass
+ elif program == 'gsymcheck':
+ arg = '-v ' + highlighted_source
+ subproc = Popen([program, arg], stdout=PIPE)
+ gedamanager.window.teo.output_textbuffer.insert(gedamanager.window.teo.output_textiter, get_time() + ' and output from ' + program + ':\n' + subproc.communicate()[0] + '.\n')
+ elif program == 'gsch2pcb workflow':
+ gsch2pcb = Gsch2pcb(gedamanager, highlighted_source)
+ elif program == 'Update PCB (gsch2pcb)':
+ not_implemented(gedamanager)
+ # The stuff below is commented out until the dependency issues
+ # are solved
+ ## # Only run if the highlighted_souce is outdated
+ ## if not gedamanager.project.dependency_status[highlighted_source]:
+ ## files_before = os.listdir(highlighted_source.rpartition('/')[0])
+ ## schematics_list = []
+ ## # TODO
+ ## if schematics_list:
+ ## schematics = ''
+ ## for sch in schematics_list:
+ ## schematics += sch + ' '
+
+ ## name = filename.split('.')[0]
+ ## subproc = Popen(['gsch2pcb', '-v','-v','-o',name,schematics]).wait()
+ ## files_after = os.listdir(highlighted_source.rpartition('/')[0])
+ ## files = [x for x in files_after if x not in files_before]
+ ## # Add any new files to the sources tree view if any
+ ## if files:
+ ## icon = gtk.IconTheme()
+ ## selection = gedamanager.sources_tree.get_selection()
+ ## model, selection_iter = selection.get_selected()
+ ## if isinstance(selection_iter, gtk.TreeIter):
+ ## parent_iter = gedamanager.sources.iter_parent(selection_iter)
+ ## wanted = ['pcb','new.pcb','net']
+ ## new_files = []
+ ## new_files.append(True)
+ ## for f in files:
+ ## if f.endswith('new.pcb'):
+ ## ext = 'new.pcb'
+ ## else:
+ ## ext = f.split('.')[-1]
+ ## if ext in wanted:
+ ## filepath = directory + '/' + f
+ ## image = icon.load_icon(icon_lut[ext], 22, 0)
+ ## # Need to see if there are any new files
+ ## new_files.append(f)
+ ## print 'new_files:',new_files
+ ## else:
+ ## print 'no new files'
+
+ ## else:
+ ## not_implemented(gedamanager)
+ ## ## TODO I will need to change the below since 'program' may
+ ## ## not be an actual program
+ ## ## subproc = Popen([program, highlighted_source])
+ ## gedamanager.processes_tree.set_sensitive(False)
+
+
+def write_logs(window, gedamanager):
+ """
+ Method to write out the error and output logs with what is in
+ the textbuffers.
+ """
+ startiter, enditer = window.output_textbuffer.get_bounds()
+ output = window.output_textbuffer.get_text(startiter, enditer)
+ os.chdir(gedamanager.project.directory)
+ f = file('output.log', 'a')
+ f.writelines(output)
+ f.close()
+
+ startiter, enditer = self.errors_textbuffer.get_bounds()
+ errors = window.errors_textbuffer.get_text(startiter, enditer)
+ os.chdir(gedamanager.project.directory)
+ f = file('error.log', 'a')
+ f.writelines(errors)
+ f.close()
+
+
+def kill_processes():
+ """
+ Method to kill all the open processes if there are still any
+ open when the gEDAManager is closed.
+ """
+ # TODO - if open processes's prompt the user to save work
+ # before exiting
+ # e.g.
+ # "You have open processes. If you exit you may lose unsaved
+ # changes. Would you like to proceed? Okay or Cancel.
+ for tool, value in tools.iteritems():
+ if value != None and not isinstance(value, str): # kill the process
+ os.kill(value.pid, signal.SIGKILL)
+
+
+
+
+ ## def update_dependency_list(gedamanager, filename, flag=False):
+ ## """!
+ ## Method to update the dependencies for filename.
+ ## @param filename file that will have its dependencies updated
+ ## or list of filenames that will have its dependencies updated
+ ## @param flag sets status of filename
+ ## """
+ ## if isinstance(filename, list):
+ ## for f in filename:
+ ## gedamanager.project.dependency_list[f][0] = flag
+ ## for x in gedamanager.project.dependency_list[f][1:]:
+ ## update_dependency_list(gedamanager, x, False)
+ ## else:
+ ## # We just need to create a new list and set that as the value
+ ## gedamanager.project.dependency_list[filename][0] = flag
+ ## for x in gedamanager.project.dependency_list[filename][1:]:
+ ## # recurse over files and make out of date
+ ## update_dependency_list(gedamanager, x, False)
+
+
+ ## def add_to_dependency_list(gedamanager, filename):
+ ## """!
+ ## Method to add a file to the project's dependency_list.
+ ## @param filename file to add to project.dependency_list
+ ## """
+ ## # add file to the dependency_list
+ ## if filename not in gedamanager.project.dependency_list:
+ ## gedamanager.project.dependency_list[filename] = [True, [], []]
+
+ ## def get_status_image(gedamanager, highlighted_source):
+ ## """!
+ ## Method to get the status image for the process.
+ ## @param gedamanager current gEDAManager instance
+ ## @param highlighted_source currently selected node in the 'Sources' tree view.
+ ## @return icon from the icon_lut structure
+ ## """
+ ## icon = gtk.IconTheme()
+ ## if highlighted_source in gedamanager.project.dependency_status:
+ ## if gedamanager.project.dependency_status[highlighted_source] != None:
+ ## if gedamanager.project.dependency_status[highlighted_source]:
+ ## return icon.load_icon(icon_lut['updated'], 22, 0)
+ ## else:
+ ## return icon.load_icon(icon_lut['outdated'], 22, 0)
diff --git a/src/utils/Icons.py b/src/utils/Icons.py
new file mode 100644
index 0000000..bd032cf
--- /dev/null
+++ b/src/utils/Icons.py
@@ -0,0 +1,169 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.utils.Icons
+#Utility class for the gEDA Manager
+#@author Newell Jensen
+
+import os, pygtk, gtk
+pygtk.require('2.0')
+from src.utils.Helpers import configfiles
+
+class Icons:
+ """
+ Class to handle the icons.
+ """
+ def __init__(self):
+ """!
+ Constructor of the Icons class.
+ """
+ self.directory = os.getcwd()
+ self.__setup__()
+
+
+ def __setup__(self):
+ """ Method to load the icon look up table and netlists list. """
+ self.tools = ['gschem','gnetlist','pcb','gattrib','gerbv','gsymcheck','gattrib','ghdl','iverilog','vvp','gspiceui','gtkwave','gwave']
+
+ # Images to import for later use
+ image = gtk.gdk.pixbuf_new_from_file('images/icons/geda-xgsch2pcb-48.png')
+ gtk.icon_theme_add_builtin_icon('gEDAManager', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/gq-folder.png')
+ gtk.icon_theme_add_builtin_icon('folder', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/application_home.png')
+ gtk.icon_theme_add_builtin_icon('project', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/page.png')
+ gtk.icon_theme_add_builtin_icon('gm', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/page_white.png')
+ gtk.icon_theme_add_builtin_icon('log', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/verilog-module.bmp')
+ gtk.icon_theme_add_builtin_icon('v', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/vhdl-module.bmp')
+ gtk.icon_theme_add_builtin_icon('vhd', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/vhdl-module.bmp')
+ gtk.icon_theme_add_builtin_icon('vhdl', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/page_white_text.png')
+ gtk.icon_theme_add_builtin_icon('other', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/chart_curve.png')
+ gtk.icon_theme_add_builtin_icon('spice', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/background-logo-icon.png')
+ gtk.icon_theme_add_builtin_icon('iverilog', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/GHDL_logo-22.png')
+ gtk.icon_theme_add_builtin_icon('ghdl', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/application_xp_terminal.png')
+ gtk.icon_theme_add_builtin_icon('terminal', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/tick.png')
+ gtk.icon_theme_add_builtin_icon('updated', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/flag_red.png')
+ gtk.icon_theme_add_builtin_icon('outdated', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/report.png')
+ gtk.icon_theme_add_builtin_icon('output', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/exclamation.png')
+ gtk.icon_theme_add_builtin_icon('errors', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/image.png')
+ gtk.icon_theme_add_builtin_icon('png', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/gerbv-22.png')
+ gtk.icon_theme_add_builtin_icon('gerbv', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/LaTeX.png')
+ gtk.icon_theme_add_builtin_icon('tex', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/money.png')
+ gtk.icon_theme_add_builtin_icon('bom', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/page_gear.png')
+ gtk.icon_theme_add_builtin_icon('config', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/bullet_wrench.png')
+ gtk.icon_theme_add_builtin_icon('cmd', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/text_align_center.png')
+ gtk.icon_theme_add_builtin_icon('txt', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/cog.png')
+ gtk.icon_theme_add_builtin_icon('out', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/cog.png')
+ gtk.icon_theme_add_builtin_icon('vvp', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/page_white_acrobat.png')
+ gtk.icon_theme_add_builtin_icon('pdf', 22, image)
+
+
+ self.icon_lut = {'pdf': 'pdf',
+ 'vvp': 'vvp',
+ 'out': 'out',
+ 'txt': 'txt',
+ 'cmd': 'cmd',
+ 'config': 'config',
+ 'bom': 'bom',
+ 'bom1': 'bom',
+ 'bom2': 'bom',
+ 'tex': 'tex',
+ 'gerbv': 'gerbv',
+ 'png': 'png',
+ 'errors': 'errors',
+ 'output': 'output',
+ 'outdated': 'outdated',
+ 'updated': 'updated',
+ 'terminal': 'terminal',
+ 'gattrib': 'geda-gattrib',
+ 'gschem': 'geda-gschem',
+ 'spice': 'spice',
+ 'gspiceui': 'spice',
+ 'iverilog': 'iverilog',
+ 'ghdl': 'ghdl',
+ 'other': 'other',
+ 'vhd': 'vhd',
+ 'vhdl': 'vhdl',
+ 'v': 'v',
+ 'log': 'log',
+ 'gm': 'gm',
+ 'project': 'project',
+ 'folder': 'folder',
+ 'terminal': 'terminal',
+ 'gEDAManager': 'gEDAManager',
+ 'sch': 'application-x-geda-schematic',
+ 'sym': 'application-x-geda-symbol',
+ 'gsymcheck': 'application-x-geda-symbol',
+ 'gsch2pcb': 'application-x-geda-gsch2pcb-project',
+ 'g2p': 'application-x-geda-gsch2pcb-project',
+ 'pcb': 'application-x-pcb-layout',
+ 'pcb.net': 'application-x-pcb-netlist',
+ 'gbr': 'application-x-gerber',
+ 'gerber': 'application-x-gerber',
+ 'cnc': 'application-x-excellon',
+ 'gnetlist': 'application-x-pcb-netlist',
+ 'net': 'application-x-pcb-netlist',
+ 'exc': 'application-x-excellon',
+ 'fp': 'application-x-pcb-footprint'}
+
+
+ def load_image(self, filepath):
+ """!
+ Method to load the image for filepath.
+ @param filepath filepath for the node file
+ @return icon_lut value for the filepath type
+ """
+ if '.' in filepath:
+ ext = filepath.split('.')[-1]
+ if ext not in self.icon_lut:
+ return self.icon_lut['other']
+ else:
+ return self.icon_lut[ext]
+ elif filepath in configfiles:
+ return self.icon_lut['config']
+ else:
+ if os.path.isdir(filepath):
+ return self.icon_lut['folder']
+ else:
+ return self.icon_lut['other']
diff --git a/src/utils/Icons.py.~1~ b/src/utils/Icons.py.~1~
new file mode 100644
index 0000000..ea74fc5
--- /dev/null
+++ b/src/utils/Icons.py.~1~
@@ -0,0 +1,169 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.utils.Icons
+#Utility class for the gEDA Manager
+#@author Newell Jensen
+
+import os, pygtk, gtk
+pygtk.require('2.0')
+
+
+class Icons:
+ """
+ Class to handle the icons.
+ """
+ def __init__(self):
+ """!
+ Constructor of the Icons class.
+ """
+ self.directory = os.getcwd()
+ self.__setup__()
+
+
+ def __setup__(self):
+ """ Method to load the icon look up table and netlists list. """
+ self.tools = ['gschem','gnetlist','pcb','gattrib','gerbv','gsymcheck','gattrib','ghdl','iverilog','vvp','gspiceui','gtkwave','gwave']
+
+ # Images to import for later use
+ image = gtk.gdk.pixbuf_new_from_file('images/icons/geda-xgsch2pcb-48.png')
+ gtk.icon_theme_add_builtin_icon('gEDAManager', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/gq-folder.png')
+ gtk.icon_theme_add_builtin_icon('folder', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/application_home.png')
+ gtk.icon_theme_add_builtin_icon('project', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/page.png')
+ gtk.icon_theme_add_builtin_icon('gm', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/page_white.png')
+ gtk.icon_theme_add_builtin_icon('log', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/verilog-module.bmp')
+ gtk.icon_theme_add_builtin_icon('v', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/vhdl-module.bmp')
+ gtk.icon_theme_add_builtin_icon('vhd', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/vhdl-module.bmp')
+ gtk.icon_theme_add_builtin_icon('vhdl', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/page_white_text.png')
+ gtk.icon_theme_add_builtin_icon('other', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/chart_curve.png')
+ gtk.icon_theme_add_builtin_icon('spice', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/background-logo-icon.png')
+ gtk.icon_theme_add_builtin_icon('iverilog', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/GHDL_logo-22.png')
+ gtk.icon_theme_add_builtin_icon('ghdl', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/application_xp_terminal.png')
+ gtk.icon_theme_add_builtin_icon('terminal', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/tick.png')
+ gtk.icon_theme_add_builtin_icon('updated', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/flag_red.png')
+ gtk.icon_theme_add_builtin_icon('outdated', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/report.png')
+ gtk.icon_theme_add_builtin_icon('output', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/exclamation.png')
+ gtk.icon_theme_add_builtin_icon('errors', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/image.png')
+ gtk.icon_theme_add_builtin_icon('png', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/gerbv-22.png')
+ gtk.icon_theme_add_builtin_icon('gerbv', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/LaTeX.png')
+ gtk.icon_theme_add_builtin_icon('tex', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/money.png')
+ gtk.icon_theme_add_builtin_icon('bom', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/page_gear.png')
+ gtk.icon_theme_add_builtin_icon('config', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/bullet_wrench.png')
+ gtk.icon_theme_add_builtin_icon('cmd', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/text_align_center.png')
+ gtk.icon_theme_add_builtin_icon('txt', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/cog.png')
+ gtk.icon_theme_add_builtin_icon('out', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/cog.png')
+ gtk.icon_theme_add_builtin_icon('vvp', 22, image)
+ image = gtk.gdk.pixbuf_new_from_file('images/bitmaps/page_white_acrobat.png')
+ gtk.icon_theme_add_builtin_icon('pdf', 22, image)
+
+
+ self.icon_lut = {'pdf': 'pdf',
+ 'vvp': 'vvp',
+ 'out': 'out',
+ 'txt': 'txt',
+ 'cmd': 'cmd',
+ 'config': 'config',
+ 'bom': 'bom',
+ 'bom1': 'bom',
+ 'bom2': 'bom',
+ 'tex': 'tex',
+ 'gerbv': 'gerbv',
+ 'png': 'png',
+ 'errors': 'errors',
+ 'output': 'output',
+ 'outdated': 'outdated',
+ 'updated': 'updated',
+ 'terminal': 'terminal',
+ 'gattrib': 'geda-gattrib',
+ 'gschem': 'geda-gschem',
+ 'spice': 'spice',
+ 'gspiceui': 'spice',
+ 'iverilog': 'iverilog',
+ 'ghdl': 'ghdl',
+ 'other': 'other',
+ 'vhd': 'vhd',
+ 'vhdl': 'vhdl',
+ 'v': 'v',
+ 'log': 'log',
+ 'gm': 'gm',
+ 'project': 'project',
+ 'folder': 'folder',
+ 'terminal': 'terminal',
+ 'gEDAManager': 'gEDAManager',
+ 'sch': 'application-x-geda-schematic',
+ 'sym': 'application-x-geda-symbol',
+ 'gsymcheck': 'application-x-geda-symbol',
+ 'gsch2pcb': 'application-x-geda-gsch2pcb-project',
+ 'g2p': 'application-x-geda-gsch2pcb-project',
+ 'pcb': 'application-x-pcb-layout',
+ 'pcb.net': 'application-x-pcb-netlist',
+ 'gbr': 'application-x-gerber',
+ 'gerber': 'application-x-gerber',
+ 'cnc': 'application-x-excellon',
+ 'gnetlist': 'application-x-pcb-netlist',
+ 'net': 'application-x-pcb-netlist',
+ 'exc': 'application-x-excellon',
+ 'fp': 'application-x-pcb-footprint'}
+
+
+ def load_image(self, filepath):
+ """!
+ Method to load the image for filepath.
+ @param filepath filepath for the node file
+ @return icon_lut value for the filepath type
+ """
+ if '.' in filepath:
+ ext = filepath.split('.')[-1]
+ if ext not in self.icon_lut:
+ return self.icon_lut['other']
+ else:
+ return self.icon_lut[ext]
+ elif filepath in self.configfiles:
+ return self.icon_lut['config']
+ else:
+ if os.path.isdir(filepath):
+ return self.icon_lut['folder']
+ else:
+ return self.icon_lut['other']
diff --git a/src/utils/ProcessDependencyEvent.py b/src/utils/ProcessDependencyEvent.py
new file mode 100644
index 0000000..c2974d5
--- /dev/null
+++ b/src/utils/ProcessDependencyEvent.py
@@ -0,0 +1,111 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.utils.ProcessDependencyEvent
+#Class to process the events from the thread executed by DependencyLoop
+#@author Newell Jensen
+
+import gobject
+from src.utils.Helpers import *
+from pyinotify import *
+
+class ProcessDependencyEvent(ProcessEvent):
+ """
+ Class to process the events from the thread executed by DependencyLoop.
+ """
+ def __init__(self, mainwindow):
+ """!
+ Constructor for the ProcessDependencyEvent class.
+ @param gedamanager current gEDAManager instance
+ """
+ self.quit = False
+ self.mw = mainwindow
+
+
+ def cb_main_thread(self, event):
+ """!
+ Method to call the 'gtk' modifying code in the main thread.
+ @param event current event that was caught for the section of
+ filesystem under watch
+ """
+ self.mw.dependencyloop.update_watch()
+ load_sources_tree(self.mw)
+ # file extensions that should be ignored
+ if not event.pathname.endswith(('-','~','#','.save','.log','.gm')):
+ if event.maskname == 'IN_MODIFY':
+ update_dependency(self.mw, event.pathname)
+ elif event.maskname == 'IN_DELETE':
+ remove_dependency(self.mw, event.pathname)
+ elif event.maskname == 'IN_CREATE':
+ add_dependency(self.mw, event.pathname)
+ elif event.maskname == 'IN_MOVED_FROM':
+ remove_dependency(self.mw, event.pathname)
+ elif event.maskname == 'IN_MOVED_TO':
+ add_dependency(self.mw, event.pathname)
+
+
+ def process_IN_MODIFY(self, event):
+ """!
+ Method to process the IN_MODIFY event from the pyinotify module.
+ @param event current IN_MODIFY event that was caught for the section of
+ filesystem under watch
+ """
+ gobject.idle_add(self.cb_main_thread, event)
+
+
+ def process_IN_DELETE(self, event):
+ """!
+ Method to process the IN_DELETE event from the pyinotify module.
+ @param event current IN_DELETE event that was caught for the section of
+ filesystem under watch
+ """
+ gobject.idle_add(self.cb_main_thread, event)
+
+
+ def process_IN_CREATE(self, event):
+ """!
+ Method to process the IN_CREATE event from the pyinotify module.
+ @param event current IN_CREATE event that was caught for the section of
+ filesystem under watch
+ """
+ gobject.idle_add(self.cb_main_thread, event)
+
+
+ def process_IN_MOVED_FROM(self, event):
+ """!
+ Method to process the IN_MOVED_FROM event from the pyinotify module.
+ @param event current IN_MOVED_FROM event that was caught for the
+ section of filesystem under watch
+ """
+ gobject.idle_add(self.cb_main_thread, event)
+
+
+ def process_IN_MOVED_TO(self, event):
+ """!
+ Method to process the IN_MOVED_FROM event from the pyinotify module.
+ @param event current IN_MOVED_FROM event that was caught for the
+ section of filesystem under watch
+ """
+ gobject.idle_add(self.cb_main_thread, event)
+
+
+
+
+
diff --git a/src/utils/ProcessDependencyEvent.py.~1~ b/src/utils/ProcessDependencyEvent.py.~1~
new file mode 100644
index 0000000..ee9bb06
--- /dev/null
+++ b/src/utils/ProcessDependencyEvent.py.~1~
@@ -0,0 +1,111 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.utils.ProcessDependencyEvent
+#Class to process the events from the thread executed by DependencyLoop
+#@author Newell Jensen
+
+import gtk, pygtk, time, gobject
+pygtk.require('2.0')
+from src.utils.Utils import *
+from pyinotify import *
+
+class ProcessDependencyEvent(ProcessEvent):
+ """
+ Class to process the events from the thread executed by DependencyLoop.
+ """
+ def __init__(self, gedamanager):
+ """!
+ Constructor for the ProcessDependencyEvent class.
+ @param gedamanager current gEDAManager instance
+ """
+ self.g = gedamanager
+ self.quit = False
+
+
+ def cb_main_thread(self, event):
+ """!
+ Method to call the 'gtk' modifying code in the main thread.
+ @param event current event that was caught for the section of
+ filesystem under watch
+ """
+ self.g.window.load_sources_tree()
+ # file extensions that should be ignored
+ if not event.pathname.endswith(('-','~','#','.save','.log','.gm')):
+ if event.maskname == 'IN_MODIFY':
+ self.g.window.update_dependency(event.pathname)
+ elif event.maskname == 'IN_DELETE':
+ self.g.window.remove_dependency(event.pathname)
+ elif event.maskname == 'IN_CREATE':
+ self.g.window.add_dependency(event.pathname)
+ elif event.maskname == 'IN_MOVED_FROM':
+ self.g.window.remove_dependency(event.pathname)
+ elif event.maskname == 'IN_MOVED_TO':
+ self.g.window.add_dependency(event.pathname)
+
+
+ def process_IN_MODIFY(self, event):
+ """!
+ Method to process the IN_MODIFY event from the pyinotify module.
+ @param event current IN_MODIFY event that was caught for the section of
+ filesystem under watch
+ """
+ gobject.idle_add(self.cb_main_thread, event)
+
+
+ def process_IN_DELETE(self, event):
+ """!
+ Method to process the IN_DELETE event from the pyinotify module.
+ @param event current IN_DELETE event that was caught for the section of
+ filesystem under watch
+ """
+ gobject.idle_add(self.cb_main_thread, event)
+
+
+ def process_IN_CREATE(self, event):
+ """!
+ Method to process the IN_CREATE event from the pyinotify module.
+ @param event current IN_CREATE event that was caught for the section of
+ filesystem under watch
+ """
+ gobject.idle_add(self.cb_main_thread, event)
+
+
+ def process_IN_MOVED_FROM(self, event):
+ """!
+ Method to process the IN_MOVED_FROM event from the pyinotify module.
+ @param event current IN_MOVED_FROM event that was caught for the
+ section of filesystem under watch
+ """
+ gobject.idle_add(self.cb_main_thread, event)
+
+
+ def process_IN_MOVED_TO(self, event):
+ """!
+ Method to process the IN_MOVED_FROM event from the pyinotify module.
+ @param event current IN_MOVED_FROM event that was caught for the
+ section of filesystem under watch
+ """
+ gobject.idle_add(self.cb_main_thread, event)
+
+
+
+
+
diff --git a/src/utils/Project.py b/src/utils/Project.py
new file mode 100644
index 0000000..818a413
--- /dev/null
+++ b/src/utils/Project.py
@@ -0,0 +1,144 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.utils.Project
+# Project class for the gEDA Manager project objects
+#@author Newell Jensen
+
+import os, sys, yaml, gtk, pygtk, gobject
+pygtk.require('2.0')
+
+
+class Project(gobject.GObject):
+ """
+ The Project class contains
+ -- name (name of the project)
+ -- directory (root directory of the project)
+ -- dependency_list (dictionary of files and their dependencies)
+ -- dependnecy_status (dictionary of files and their updated/outdated status)
+ """
+ __gsignals__ = {'closed': (gobject.SIGNAL_NO_RECURSE,
+ gobject.TYPE_NONE,
+ (gobject.TYPE_BOOLEAN, )),
+ 'opened': (gobject.SIGNAL_NO_RECURSE,
+ gobject.TYPE_NONE,
+ (gobject.TYPE_BOOLEAN, )),
+ 'created': (gobject.SIGNAL_NO_RECURSE,
+ gobject.TYPE_NONE,
+ (gobject.TYPE_BOOLEAN, )),
+ }
+
+
+ def __init__(self, filepath=None):
+ """ Default Constructor. """
+ gobject.GObject.__init__(self)
+
+ if filepath != None:
+ try:
+ self.name = filepath.rsplit('/')[-1].split('.')[0]
+ self.directory = filepath.rpartition('/')[0]
+ # open up project file
+ project = yaml.load(open(filepath))
+ except IOError:
+ project = 0
+ except yaml.YAMLError, exc:
+ if hasattr(exc, 'problem_mark'):
+ mark = exc.problem_mark
+ print 'There is an error in the' + filepath + 'file.\n'
+ print "Error position: (%s:%s)" % (mark.line+1, mark.column+1)
+ exit(-1)
+
+ if project:
+ # parse the config object and get list of apps
+ stream = file(filepath, 'r')
+ for data in yaml.load_all(stream):
+ self.dependency_status = data['dependency_status']
+ self.dependency_list = data['dependency_list']
+ stream.close()
+ elif not project:
+ self.dependency_status = None
+ self.dependency_list = None
+ else:
+ self.name = None
+ self.directory = None
+ self.dependency_status = None
+ self.dependency_list = None
+ self.clean = False
+
+
+ def close(self):
+ """
+ Method to close the current project and then
+ emit the 'closed' signal.
+ """
+ self.name = None
+ self.directory = None
+ self.dependency_status = None
+ self.dependency_list = None
+ self.emit('closed', True)
+
+
+ def create(self):
+ """
+ Method to save the project and then emit the
+ 'created' signal.
+ """
+ self.save(True)
+ self.emit('created', True)
+
+
+ def save(self):
+ """
+ Method to save the project file.
+ """
+ if self.name != None and self.directory != None:
+ filepath = self.directory + '/' + self.name + '.gm'
+ try:
+ stream = file(filepath, 'w')
+ yaml.dump({'project': filepath,
+ 'dependency_list': self.dependency_list,
+ 'dependency_status': self.dependency_status},
+ stream, default_flow_style=False)
+ stream.close()
+ except IOError:
+ print 'IOError:', sys.exc_info()[0]
+ self.clean = True
+
+
+ def open(self, filepath):
+ """!
+ Method to open up project from path and set as current project
+ @param filepath filepath of the project file to open
+ """
+ self.name = filepath.rsplit('/')[-1].split('.')[0]
+ self.directory = filepath.rpartition('/')[0]
+ try:
+ stream = file(filepath, 'r')
+ for data in yaml.load_all(stream):
+ self.dependency_status = data['dependency_status']
+ self.dependency_list = data['dependency_list']
+ self.clean = True
+ self.emit('opened', True)
+ except IOError:
+ print 'IOError:', sys.exc_info()[0]
+
+gobject.type_register(Project)
+
+
diff --git a/src/utils/Settings.py b/src/utils/Settings.py
new file mode 100644
index 0000000..e40544a
--- /dev/null
+++ b/src/utils/Settings.py
@@ -0,0 +1,141 @@
+"""
+gEDA Manager
+Copyright (C) 2008 Newell Jensen
+Copyright (C) 2008 gEDA Contributors (see ChangeLog for details)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+##@package src.utils.Settings
+#Create and verify settings for the gEDA Manager
+#Create and update the gEDA Manager configuration file .gmrc
+#@author Newell Jensen
+
+import os, sys, gtk, string, signal, yaml
+from subprocess import *
+
+
+class Settings:
+ """
+ Settings for the gEDA Manager.
+ This class takes care of configuring
+ the applicaton settings.
+ """
+ def __init__(self):
+ """ Settings Default Constructor. """
+ self.version = 0.1
+ ## self.installed_apps = []
+ self.project = None
+ self.editor = None
+ self.path = os.path.expanduser('~') + '/.gmrc'
+ ## self.geda_apps = ['gschem','pcb','gsch2pcb','gnucap','ngspice',
+ ## 'iverilog','gattrib','gtkwave','gwave','gnetlist',
+ ## 'tragesym','grenum','gerbv','wcalc','mcalc','olib']
+ try:
+ config = yaml.load(open(self.path))
+ except IOError:
+ config = 0
+ except yaml.YAMLError, exc:
+ if hasattr(exc, 'problem_mark'):
+ mark = exc.problem_mark
+ print "There is an error in the .gmrc file.\n"
+ print "Error position: (%s:%s)" % (mark.line+1, mark.column+1)
+ exit(-1)
+
+ if config:
+ # parse the config object and get list of apps
+ stream = file(self.path, 'r')
+
+ for data in yaml.load_all(stream):
+ ## self.installed_apps = data['programs']
+ self.project = data['project']
+ self.editor = data['editor']
+ # Check to see if this file is still available
+ if self.project != None:
+ try:
+ f = open(self.project)
+ except IOError:
+ md = gtk.MessageDialog(None,
+ (gtk.DIALOG_MODAL |
+ gtk.DIALOG_DESTROY_WITH_PARENT),
+ gtk.MESSAGE_ERROR,
+ gtk.BUTTONS_OK)
+ md.set_markup('<span weight="bold" size="larger">Could not open project: ' + self.project + '.</span>')
+ error_image = gtk.image_new_from_stock('gtk-dialog-error',
+ gtk.ICON_SIZE_DIALOG)
+ error_image.show()
+ md.set_image(error_image)
+ md.show_all
+ md.run()
+ md.hide_all()
+ self.project = None
+ stream.close()
+ elif not config:
+ # find installed apps and create the config file
+ ## self.installed_apps = self.find_installed_apps()
+ self.create_config_file()
+
+
+ ## def find_installed_apps(self):
+ ## """!
+ ## Find all of the gEDA suite applications that are
+ ## installed on this machine and return list of these programs.
+ ## @return list of installed geda apps
+ ## """
+ ## apps = []
+ ## for app in self.geda_apps:
+ ## # Check to see if program is installed
+ ## args = 'which ' + app
+ ## path = Popen(['which', app], stdout=PIPE).communicate()[0]
+ ## #get name from path
+ ## path = path.strip('\n')
+ ## geda_app = path.rsplit('/',1)
+ ## try:
+ ## apps.append(geda_app[1])
+ ## except IndexError:
+ ## print 'IndexError:', sys.exc_info()[0]
+ ## print 'The application ' + app + ' is not installed.'
+ ## return apps
+
+
+ def create_config_file(self):
+ """ Create the configuration file for the gEDA Manager. """
+ stream = file(self.path, 'w')
+ document = """
+ purpose: |
+
+ .gmrc is the configuration file for the gEDA Manager.
+ It stores the list of geda programs that the user wants to
+ include in the manager. This file can be edited so that only
+ the programs of interest will be visible to the manager. To
+ do this simply edit the list of programs below. However, if
+ you edit this file and add a program it is your responsibility
+ to make sure that this program is installed on your system.
+ If this program is not installed on your system, this will
+ cause errors and/or undesirable functionality.
+
+ In the case that someone creates a new geda application and would
+ like it to be included in the gEDA Manager workflow, you will need
+ to update the geda_apps list located in the Settings.__init__
+ method in the settings.py file.
+
+ """
+ yaml.dump(yaml.load(document), stream, default_flow_style=False)
+ yaml.dump({'version': self.version,
+ 'project': self.project,
+ 'editor': self.editor}, stream, default_flow_style=False)
+ stream.close()
+
+
diff --git a/src/utils/__init__.py b/src/utils/__init__.py
new file mode 100644
index 0000000..e69de29
_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs