[pygccxml-commit] SF.net SVN: pygccxml: [1029] pyplusplus_dev/ide
Brought to you by:
mbaas,
roman_yakovenko
|
From: <ale...@us...> - 2007-05-02 14:59:12
|
Revision: 1029
http://svn.sourceforge.net/pygccxml/?rev=1029&view=rev
Author: alex_eisen
Date: 2007-05-02 07:58:58 -0700 (Wed, 02 May 2007)
Log Message:
-----------
Working ide without code generation
Modified Paths:
--------------
pyplusplus_dev/ide/controllers/__init__.py
pyplusplus_dev/ide/controllers/controller_main.py
pyplusplus_dev/ide/ide.py
pyplusplus_dev/ide/model/__init__.py
pyplusplus_dev/ide/views/frame_main.py
Added Paths:
-----------
pyplusplus_dev/ide/IdeTemplate.xml
pyplusplus_dev/ide/ProjectTemplate.xml
pyplusplus_dev/ide/doc/
pyplusplus_dev/ide/doc/EnterpriseArchitectModel.eap
pyplusplus_dev/ide/doc/IdeInBoa.png
pyplusplus_dev/ide/doc/PackageOverview.png
pyplusplus_dev/ide/doc/ReadmeForDevelopment.odt
pyplusplus_dev/ide/model/code_generator.py
pyplusplus_dev/ide/model/etree_extension.py
pyplusplus_dev/ide/model/settings.py
pyplusplus_dev/ide/test/
pyplusplus_dev/ide/test/test_attrib_finder.py
Removed Paths:
-------------
pyplusplus_dev/ide/model/ProjectFileTemplatate.xml
Added: pyplusplus_dev/ide/IdeTemplate.xml
===================================================================
--- pyplusplus_dev/ide/IdeTemplate.xml (rev 0)
+++ pyplusplus_dev/ide/IdeTemplate.xml 2007-05-02 14:58:58 UTC (rev 1029)
@@ -0,0 +1,9 @@
+<!-- Template file for pyplusplus IDE -->
+<pyPPIde>
+ <project
+ maxNumInMenue="6"
+ recentProjects="[]"
+ lastPrjPath="."
+ lastIncPath="."
+ />
+</pyPPIde>
\ No newline at end of file
Added: pyplusplus_dev/ide/ProjectTemplate.xml
===================================================================
--- pyplusplus_dev/ide/ProjectTemplate.xml (rev 0)
+++ pyplusplus_dev/ide/ProjectTemplate.xml 2007-05-02 14:58:58 UTC (rev 1029)
@@ -0,0 +1,11 @@
+<pyPPProject>
+ <gccXmlSettings
+ gccXmlPath=""
+ headerPath=""
+ includePathList="[]"
+ macroList="[]" />
+ <guiGeometry
+ horizontalSplitter="350"
+ size="(0, 0, 800, 600)"
+ verticalSplitter="300" />
+</pyPPProject>
\ No newline at end of file
Modified: pyplusplus_dev/ide/controllers/__init__.py
===================================================================
--- pyplusplus_dev/ide/controllers/__init__.py 2007-05-01 18:06:08 UTC (rev 1028)
+++ pyplusplus_dev/ide/controllers/__init__.py 2007-05-02 14:58:58 UTC (rev 1029)
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+# Copyright 2004 Roman Yakovenko.
+# 2007 Alexander Eisenhuth
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
Modified: pyplusplus_dev/ide/controllers/controller_main.py
===================================================================
--- pyplusplus_dev/ide/controllers/controller_main.py 2007-05-01 18:06:08 UTC (rev 1028)
+++ pyplusplus_dev/ide/controllers/controller_main.py 2007-05-02 14:58:58 UTC (rev 1029)
@@ -4,63 +4,338 @@
# Distributed under the Boost Software License, Version 1.0. (See
# accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
-
+from threading import Timer
+from Queue import Queue, Empty
+import os
import wx
from views import dialog_macro
+from model.settings import ProjectSettings, IdeSettings, ParameterContainer
+import model.code_generator as code_generator
-""" Contoller class. Part of MVC
-Responsibility: Glue view and model code:
-- Handle all events from view (p.e. button) """
+class MainParameter(object):
+ '''
+ Abstract main parameters
+ '''
+ def __init__(self):
+
+ object.__init__(self)
+
+ # Following attributes are parameters of the ide (realized as properties)
+ self.max_num_recent_projects = ParameterContainer(int, 0)
+ self.recent_prj_list = ParameterContainer(list, [])
+ self.last_prj_path = ParameterContainer(unicode, "")
+ self.last_inc_path = ParameterContainer(unicode, "")
+
+class AsyncExecHandler(wx.EvtHandler):
+ '''
+ This class handles async execution. It exec the callable given in the
+ constructor. There are some callbacs for misc. issues
+ '''
+
+ def __init__(self, async_callable, args):
+ wx.EvtHandler.__init__(self)
+ self._async_callable = async_callable
+ self._args = args
+ self._cur_timer_calls = 0
+ self._ui_eventhanler = None
+ self._timer_res = 100 # 100 msec
+
+ def GetRunning(self):
+ '''
+ Return boolean if async execution is running
+ '''
+ return not self._thread.finished.isSet()
+
+ def Start(self):
+ '''
+ Start async execution
+ '''
+ self._start_in_thread()
+
+ def SetErrorOutput(self, err_cb):
+ '''
+ Set callback for error output
+ @param err_cb: callback
+ '''
+ self._err_cb = err_cb
+
+ def SetResultOutput(self, result_cb):
+ '''
+ Set callback for result
+ @param result_cb: callback
+ '''
+ self._result_cb = result_cb
+
+ def SetProgressCb(self, progress_cb, progress_tm_100msec):
+ '''
+ Set callback for progress. Param progress_tm_100msec defines the time
+ to call the callback while async execution is running
+ @param progress_cb: callback
+ @param progress_tm_100msec: time in 100 msec
+ '''
+ assert(isinstance(progress_tm_100msec, int))
+ self._progress_cb = progress_cb
+ self._num_timer_calls = progress_tm_100msec
+
+ def SetFinishedCb(self, finished_cb):
+ '''
+ Set callback, when async execution has finished
+ @param finished_cb: callback
+ '''
+ self.finished_cb = finished_cb
+
+ def _notify(self, event):
+ # Read from result queue and error queue
+ for que_obj, cb_obj in zip( \
+ [self._q_err, self._q_result],
+ [self._err_cb, self._result_cb]):
+
+ try:
+ txt_element = que_obj.get(False)
+ cb_obj(txt_element)
+ except Empty:
+ pass
+
+ if self._thread.finished.isSet():
+ self._wxtimer.Stop()
+ self.finished_cb()
+ else:
+ pass
+
+ self._cur_timer_calls += 1
+
+ # self._num_timer_calls is set in SetProgressCb
+ if self._cur_timer_calls % self._num_timer_calls == 0:
+ self._progress_cb()
+
+ event.Skip()
+
+ def _start_in_thread(self):
+ # Start python thread and wx timer
+ self._q_result = Queue()
+ self._q_err = Queue()
+
+ self._thread = Timer(0, self._async_callable, [self._args,
+ self._q_result, self._q_err])
+ self._thread.start()
+
+ self._wxtimer = wx.Timer(self)
+ self._wxtimer.SetOwner(self)
+ self.Bind(wx.EVT_TIMER, self._notify)
+ self._wxtimer.Start(self._timer_res)
+
+
class MainController:
+ """ Contoller class. Part of MVC
+ Responsibility: Glue view and model code:
+ - Handle all events from view (p.e. button)
+ """
def __init__(self, view):
self._view = view
# Give controller object to the view
self._view.set_controller(self)
-
+
+ # Template file for new project
+ self._prjTemplateFile = "./ProjectTemplate.xml"
+
+ # Tag to appera in title of main window
+ self._changedTag = " [changed]"
+
+ # Dict with id's of recent projects
+ self._recentPrjDict = {}
+
+ # Parameters
+ self.param = MainParameter()
+
+ # To access prj settings (settings are related to view)
+ self._prj_settings = ProjectSettings(self._view, None)
+
+ # To access ide settings (settings are related to MainParameter)
+ self._ide_settings = IdeSettings(None, self.param)
+
+ # To count code generation durance
+ self._tm_code_gen = 0
+
+ # Object to control async execution
+ self._async_runner = None
+
+ self._setup_ide_settings()
+
+ def ExitIde(self):
+ '''
+ Exit IDE. Exit can be canceled.
+ @return: False if exit is canceled else True
+ '''
+ if not self._check_and_save_project():
+ return False
+
+ if self._async_runner != None:
+ if self._async_runner.GetRunning():
+ self.OutputWarning("Cannot exit. "\
+ "Ide is doing async execution ...")
+ return False
+
+ new_list = []
+
+ # build list with max max_num_recent_projects elements
+ last_idxs = self._recentPrjDict.keys()
+ last_idxs.reverse() # Last added should be saved
+ for idx in last_idxs:
+ new_list.append(self._recentPrjDict[idx])
+ if len(new_list) >= self.param.max_num_recent_projects.get():
+ break
+
+ self.param.recent_prj_list.set(new_list)
+
+ self._ide_settings.save()
+
+ self._view.Destroy()
+
+ return True
+
+ def OnRecentPrjLoad(self, event):
+ '''
+ Callback from the file menue. (Recent projects)
+ @param event: wx event.
+ '''
+ project_file_name = self._recentPrjDict[event.GetId()]
+ self._load_project(project_file_name)
+
def DoRemoveCurInclude(self):
- """Remove current selected Include item"""
+ '''
+ Remove current selected Include item
+ '''
+
cur_num = self._view.currentItemInclude
if None == cur_num:
return
self._view.listIncludes.DeleteItem(cur_num)
+ self._set_settings_changed()
def DoRemoveCurMacro(self):
- """Remove current selected Macro item"""
+ '''
+ Remove current selected Macro item
+ '''
+
cur_num = self._view.currentItemMacro
if None == cur_num:
return
self._view.listMacros.DeleteItem(cur_num)
+ self._set_settings_changed()
+
+
+ def CountCodeGenSec(self, reset=False):
+ '''
+ Count the time of code generation. Must be called once per second.
+ Update UI
+ @param reset: Boolean to reset the counter
+ '''
+ if reset:
+ self._tm_code_gen = 0
+ else:
+ self._tm_code_gen += 1
+ self._view.statusBar.SetStatusText(number=1, text=u'Time: %d sec' % \
+ self._tm_code_gen)
- def GenXmlCode(self):
- """ Generate XML code"""
- self._appendOutText("Generation of XML code staretd")
+ def OutputError(self, err_txt):
+ '''
+ Print error text in output window
+ @param err_txt: Text to display
+ '''
+ self._append_out_text(err_txt, self._text_error)
- for i in range(0,5):
- self._view.listIncludes.InsertStringItem(i, "First Element - this is a long")
-
+ def OutputWarning(self, err_txt):
+ '''
+ Print warning text in output window
+ @param err_txt: Text to display
+ '''
+ self._append_out_text(err_txt, self._text_warn)
+
+ def OutputInfo(self, inf_txt):
+ '''
+ Print info text in output window
+ @param inf_txt:
+ '''
+ self._append_out_text(inf_txt, self._text_info)
+
+ def OutputCode(self, code_txt):
+ '''
+ Append text in the code window
+ @param code_txt: Text to append
+ '''
+ self._view.textCode.AppendText(code_txt)
+
+ def GenCodeFinished(self):
+ '''
+ Inform that code generation has finished
+ '''
+ self._enable_generation_widgets(True)
+
+
def GenCppCode(self):
- """ Generate Boost.Python code"""
- self._appendOutText("Generation of C++ code for Boost.Python started")
+ '''
+ Generate Boost.Python code
+ '''
+ self._enable_generation_widgets(False)
+ self._view.textCode.SetValue("")
+ self._append_out_text("Generation of C++ code for Boost.Python started")
+ self.CountCodeGenSec(reset=True)
+ params = self._get_gccxml_params(False)
+
+ gen_xml_obj = AsyncExecHandler(code_generator.gen_cpp, params)
+ self._start_async_exec(gen_xml_obj)
+
def GenPyPPCode(self):
- """ Generate Py++ code"""
- self._appendOutText("Generation of Py++ code started")
+ '''
+ Generate Py++ code
+ '''
+ self._enable_generation_widgets(False)
+ self._view.textCode.SetValue("")
+ self._append_out_text("Generation of Py++ code started")
+ self.CountCodeGenSec(reset=True)
+ params = self._get_gccxml_params(False)
+
+ gen_xml_obj = AsyncExecHandler(code_generator.gen_pypp, params)
+ self._start_async_exec(gen_xml_obj)
+
+ def GenXmlCode(self):
+ '''
+ Generate XML code
+ '''
+ self._enable_generation_widgets(False)
+ self._append_out_text("Generation of XML code started")
+ self._view.textCode.SetValue("")
+ self.CountCodeGenSec(reset=True)
+
+ params = self._get_gccxml_params(False)
+
+ gen_xml_obj = AsyncExecHandler(code_generator.gen_xml, params)
+ self._start_async_exec(gen_xml_obj)
+
def OpenDlgHeader(self):
- """Open dialog to get header file"""
- self._openFileDlgWithRelatedWxText( self._view.textHeader,
+ '''
+ Open dialog to get header file
+ '''
+ self._open_file_dlg_text_ctrl( self._view.textHeader,
"Choose a Header file",
"Header (*.h)|*.h|All Files(*)|*")
def OpenDlgGccXml(self):
- """Open dialog to get GccXml executable"""
- self._openFileDlgWithRelatedWxText( self._view.textGccXml,
+ '''
+ Open dialog to get GccXml executable
+ '''
+
+ self._open_file_dlg_text_ctrl( self._view.textGccXml,
"Choose GccXml executable",
"All Files(*)|*")
def OpenDlgEditCurInclude(self):
- """ """
+ '''
+ Open dialog to edit current include
+ '''
cur_num = self._view.currentItemInclude
if None == cur_num:
return
@@ -71,11 +346,14 @@
self._view.listIncludes.DeleteItem(cur_num)
self._view.listIncludes.InsertStringItem(
cur_num, dialog.GetPath())
+ self._set_settings_changed()
finally:
dialog.Destroy()
def OpenDlgEditCurMacro(self):
- """ """
+ '''
+ Open dialog to edit current macro
+ '''
cur_num = self._view.currentItemMacro
if None == cur_num:
return
@@ -87,12 +365,16 @@
new_macro = dialog.textMacro.GetLineText(0)
self._view.listMacros.InsertStringItem(cur_num, new_macro)
+ self._set_settings_changed()
finally:
dialog.Destroy()
def OpenDlgAddInclude(self):
- """ """
- dialog = wx.DirDialog(self._view, "Choose include directory", ".")
+ '''
+ Open Dialog to add a include path
+ '''
+ dialog = wx.DirDialog(self._view, "Choose include directory",
+ self.param.last_inc_path.get())
try:
if dialog.ShowModal() == wx.ID_OK:
@@ -100,16 +382,20 @@
dir_path = dialog.GetPath()
# Check weather path is already in list
- if not self._checkItemIsInList(dir_path,
+ if not self._check_item_in_list(dir_path,
self._view.listIncludes):
self._view.listIncludes.InsertStringItem(
cur_num, dir_path)
+ self.param.last_inc_path.set(str(dir_path))
+ self._set_settings_changed()
finally:
dialog.Destroy()
def OpenDlgAddMacro(self):
- """ """
+ '''
+ Open dialog to add a macro
+ '''
dialog = dialog_macro.MacroDialog(self._view)
if dialog.ShowModal() == wx.OK:
@@ -118,12 +404,192 @@
new_macro = dialog.textMacro.GetLineText(0)
# Check weather macro is already in list
- if not self._checkItemIsInList(new_macro, self._view.listMacros):
+ if not self._check_item_in_list(new_macro, self._view.listMacros):
self._view.listMacros.InsertStringItem(cur_num, new_macro)
+ self._set_settings_changed()
+
+ def OpenDlgLoadProject(self):
+ '''
+ Open dialog to load a project
+ '''
+ from xml.parsers.expat import ExpatError
+
+ dialog = wx.FileDialog(self._view, "Load existing Py++ project",
+ self.param.last_prj_path.get(),
+ "", "Project files (*.xml)|*.xml|All Files(*)|*", wx.OPEN)
+
+ try:
+ if dialog.ShowModal() == wx.ID_OK:
+ self.ClearUi()
+ project_file_name = dialog.GetPath()
+ self._load_project(project_file_name)
+
+ except ExpatError:
+ self._append_out_text("XML parser error in file:%s" % \
+ dialog.GetPath(), self._text_error)
+ except Exception:
+ self._append_out_text("Error loading file:%s" % \
+ dialog.GetPath(), self._text_error)
+ raise
+
+ finally:
+ dialog.Destroy()
+
+ def OpenDlgSaveProject(self, new_file=False):
+ '''
+ Open dialog to save a project
+ @param new_file: Boolean weather to use a new file
+ @return: False if project save was canceled
+ '''
+ # Is current file prj template?
+ if self._prj_settings.get_file_name() == self._prjTemplateFile:
+ project_file_name = self._open_new_prj_file()
+ else:
+ if new_file:
+ project_file_name = self._open_new_prj_file()
+ else:
+ project_file_name = self._prj_settings.get_file_name()
+
+ try:
+ if project_file_name == None:
+ return False # prior dialog skipped
+
+ if not self._save_project(project_file_name):
+ return False
+ except Exception:
+ self._append_out_text("Error saving file:%s" % \
+ project_file_name, self._text_error)
+ raise
+
+ return True
+
+ def DoProjectNew(self):
+ '''
+ Open dialog for new Project
+ '''
+ self._load_project(self._prjTemplateFile)
+
+ def ClearUi(self):
+ '''
+ Clear all controls of UI
+ '''
+
+ # Clear text ctrls
+ for textCtrl in [self._view.textHeader, self._view.textGccXml,
+ self._view.textOutput, self._view.textCode]:
+ textCtrl.Clear()
+
+ # clear list ctrls
+ for listCtrl in [self._view.listMacros, self._view.listIncludes]:
+ tot_num = listCtrl.GetItemCount()
+ for cur_num in range(tot_num, 0, -1):
+ listCtrl.DeleteItem(cur_num-1)
+ def _cancel_if_file_exist(self, project_file_name, parent_dlg=None):
+ # check for overwriting of file
+ if os.path.exists(project_file_name):
+ dialog = wx.MessageDialog(parent_dlg,
+ "%s exists. Should it be overwritten?" % \
+ (project_file_name), pos=self._view.GetPosition())
+
+ if dialog.ShowModal() == wx.ID_CANCEL:
+ return True
+ else:
+ return False
- def _openFileDlgWithRelatedWxText(self,
+ # Return True if successfull
+ def _check_and_save_project(self):
+ if self._prj_settings.get_changed():
+
+ # Anyhow pos is working
+ dialog = wx.MessageDialog(self._view, "Current project changed. "\
+ "Should project be saved?", style = (wx.YES_NO),
+ pos=self._view.GetPosition())
+
+ user_input = dialog.ShowModal()
+ dialog.Destroy()
+
+ if user_input == wx.ID_NO:
+ return True
+ elif user_input == wx.ID_YES:
+ return self.OpenDlgSaveProject()
+ else:
+ return True
+
+ def _load_project(self, project_file_name):
+ self._check_and_save_project()
+ self.ClearUi()
+ self._prj_settings.load(project_file_name)
+ self._set_prj_filename_in_title(project_file_name)
+
+ if project_file_name != self._prjTemplateFile:
+ self.param.last_prj_path.set(unicode(os.path.dirname(project_file_name)))
+
+ self._add_to_prj_history(project_file_name)
+
+ def _save_project(self, project_file_name):
+
+ self._prj_settings.save(project_file_name)
+ self._reset_settings_changed()
+ self.param.last_prj_path.set(os.path.dirname(project_file_name))
+ self._set_prj_filename_in_title(project_file_name)
+ self._add_to_prj_history(project_file_name)
+
+ return True
+
+
+ def _open_new_prj_file(self):
+
+ project_file_name = None
+
+ dialog = wx.FileDialog(self._view,
+ "Save Py++ project to new file", self.param.last_prj_path.get(), "",
+ "Project files (*.xml)|*.xml|All Files(*)|*", wx.FD_SAVE)
+
+ if dialog.ShowModal() == wx.ID_OK:
+
+ project_file_name = dialog.GetPath()
+
+ if self._cancel_if_file_exist(project_file_name, dialog):
+ project_file_name = None
+
+ dialog.Destroy()
+
+ return project_file_name
+
+ def _add_to_prj_history(self, prj_filename):
+
+# This don't work, see below
+# max_num_history = self.param.max_num_recent_projects.get()
+
+
+ if prj_filename in self._recentPrjDict.values():
+ return
+
+ if prj_filename == self._prjTemplateFile:
+ return
+
+ file_name = os.path.split(prj_filename)[1]
+
+ menue = self._view.menueRecentPrj
+ new_item_id = id=wx.NewId()
+ new_item = wx.MenuItem(menue, help=prj_filename,
+ id=new_item_id,
+ kind=wx.ITEM_NORMAL, text=file_name)
+
+ menue.PrependItem(new_item)
+
+ self._view.Bind(wx.EVT_MENU, self.OnRecentPrjLoad,
+ id=new_item_id)
+
+ self._recentPrjDict[new_item_id] = prj_filename
+
+# Doesn't work. Dont know why
+# if menue.GetMenuItemCount() > max_num_history:
+# menue.Remove(max_num_history)
+
+ def _open_file_dlg_text_ctrl(self,
related_wx_text,
caption_txt="",
file_filter="All Files(*)|*",
@@ -135,10 +601,67 @@
if dialog.ShowModal() == wx.ID_OK:
related_wx_text.Clear()
related_wx_text.AppendText(dialog.GetPath())
+ self._set_settings_changed()
finally:
dialog.Destroy()
- def _checkItemIsInList(self, item, wx_list):
+ def _set_settings_changed(self):
+ self._prj_settings.set_changed()
+ title_str = self._view.GetTitle()
+ if not self._changedTag in title_str:
+ title_str += self._changedTag
+ self._view.SetTitle(title_str)
+
+ def _enable_generation_widgets(self, state):
+ ctrls = [self._view.butGenCpp, self._view.butGenXml, \
+ self._view.butGenPyPP]
+
+ for ctrl in ctrls:
+ ctrl.Enable(state)
+
+ def _get_gccxml_params(self, verbose):
+
+ gcc_xml = self._prj_settings.get_param('gccXmlSettings.gccXmlPath')
+ inc_path_list = eval(self._prj_settings.get_param(
+ 'gccXmlSettings.includePathList'))
+ macro_list = eval(self._prj_settings.get_param(
+ 'gccXmlSettings.macroList'))
+
+ if verbose:
+ self._append_out_text(" "+ gcc_xml)
+ self._append_out_text(" "+ str(inc_path_list))
+ self._append_out_text(" "+ str(macro_list))
+
+
+ return (gcc_xml, inc_path_list, macro_list)
+
+ def _setup_ide_settings(self):
+
+ # load ide settings
+ self._ide_settings.load()
+ prj_list = self.param.recent_prj_list.get()
+ prj_list.reverse()
+ for prj in prj_list:
+ self._add_to_prj_history(prj)
+
+ def _set_prj_filename_in_title(self, filename):
+
+ if filename == self._prjTemplateFile:
+ filename = "New project"
+
+ title_str = self._view.GetTitle()
+ start_idx = title_str.find("(")
+ end_idx = title_str.find(")")
+ fnamstr = title_str[start_idx:end_idx+1]
+ title_str = title_str.replace(fnamstr, "(" + filename + ")")
+ self._view.SetTitle(title_str)
+
+ def _reset_settings_changed(self):
+ title_str = self._view.GetTitle()
+ title_str = title_str.replace(self._changedTag, "")
+ self._view.SetTitle(title_str)
+
+ def _check_item_in_list(self, item, wx_list):
idx = wx_list.FindItem(0, item)
if idx == -1:
return False
@@ -146,7 +669,7 @@
return True
- def _appendOutText(self, text, type_of_text = 0):
+ def _append_out_text(self, text, type_of_text = 0):
""" append text with different error level"""
text_ctrl = self._view.textOutput
type_txt = "INFO"
@@ -164,7 +687,16 @@
text_ctrl.SetDefaultStyle(wx.TextAttr(wx.BLACK))
text_ctrl.AppendText(type_txt + ": " + text + "\n")
+ # Start async execution
+ def _start_async_exec(self, async_runner):
+ self._async_runner = async_runner
+ self._async_runner.SetErrorOutput(self.OutputError)
+ self._async_runner.SetResultOutput(self.OutputCode)
+ self._async_runner.SetFinishedCb(self.GenCodeFinished)
+ self._async_runner.SetProgressCb(self.CountCodeGenSec, 10)
+ self._async_runner.Start()
+ # levels
_text_info = 0 # Text has informational character
_text_warn = 1 # Text has warning character
_text_error = 2 # Text has error character
Added: pyplusplus_dev/ide/doc/EnterpriseArchitectModel.eap
===================================================================
(Binary files differ)
Property changes on: pyplusplus_dev/ide/doc/EnterpriseArchitectModel.eap
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: pyplusplus_dev/ide/doc/IdeInBoa.png
===================================================================
(Binary files differ)
Property changes on: pyplusplus_dev/ide/doc/IdeInBoa.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: pyplusplus_dev/ide/doc/PackageOverview.png
===================================================================
(Binary files differ)
Property changes on: pyplusplus_dev/ide/doc/PackageOverview.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: pyplusplus_dev/ide/doc/ReadmeForDevelopment.odt
===================================================================
(Binary files differ)
Property changes on: pyplusplus_dev/ide/doc/ReadmeForDevelopment.odt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: pyplusplus_dev/ide/ide.py
===================================================================
--- pyplusplus_dev/ide/ide.py 2007-05-01 18:06:08 UTC (rev 1028)
+++ pyplusplus_dev/ide/ide.py 2007-05-02 14:58:58 UTC (rev 1029)
@@ -28,6 +28,9 @@
self.main.Show()
self.SetTopWindow(self.main)
+
+ controller.DoProjectNew()
+
return True
def main():
Deleted: pyplusplus_dev/ide/model/ProjectFileTemplatate.xml
===================================================================
--- pyplusplus_dev/ide/model/ProjectFileTemplatate.xml 2007-05-01 18:06:08 UTC (rev 1028)
+++ pyplusplus_dev/ide/model/ProjectFileTemplatate.xml 2007-05-02 14:58:58 UTC (rev 1029)
@@ -1,10 +0,0 @@
-<!-- Template file for pyplusplus IDE -->
-<pyPPProject>
- <gccXmlSettings
- headerPath=""
- includePathList="[]"
- gccXmlPath=""
- macroList="[]"
- />
- </gccXmlSettings>
-</pyPPProject>
\ No newline at end of file
Modified: pyplusplus_dev/ide/model/__init__.py
===================================================================
--- pyplusplus_dev/ide/model/__init__.py 2007-05-01 18:06:08 UTC (rev 1028)
+++ pyplusplus_dev/ide/model/__init__.py 2007-05-02 14:58:58 UTC (rev 1029)
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+# Copyright 2004 Roman Yakovenko.
+# 2007 Alexander Eisenhuth
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
Added: pyplusplus_dev/ide/model/code_generator.py
===================================================================
--- pyplusplus_dev/ide/model/code_generator.py (rev 0)
+++ pyplusplus_dev/ide/model/code_generator.py 2007-05-02 14:58:58 UTC (rev 1029)
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+# Copyright 2004 Roman Yakovenko.
+# 2007 Alexander Eisenhuth
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+'''
+Code generation is started in a own thread. To exchange data, queues
+are used.
+'''
+
+import time
+
+def gen_xml(params, q_result, q_error):
+ '''
+ Generate XML code
+ @param params: List of parameters [gccxml,incPath,macros]
+ @param q_result: python queue to put result in
+ @param q_error: python queue to put error in
+ @return None (isn't evaluated)
+ '''
+
+ gcc_xml = params[0]
+ inc_path_list = params[1]
+ macro_list = params[2]
+
+ time.sleep(1)
+ q_result.put("This is dummy data of gen_xml\n")
+ q_error.put("This is dummy error gen_xml")
+ time.sleep(4)
+ q_result.put("This is dummy data of gen_xml")
+ q_error.put("This is dummy error of gen_xml")
+
+def gen_cpp(params, q_result, q_error):
+ '''
+ Generate cpp (Boost.Python) code
+ @param params: List of parameters [gccxml,incPath,macros]
+ @param q_result: python queue to put result in
+ @param q_error: python queue to put error in
+ @return None (isn't evaluated)
+ '''
+ pass
+
+def gen_pypp(params, q_result, q_error):
+ '''
+ Generate Python (Py++) code
+ @param params: List of parameters [gccxml,incPath,macros]
+ @param q_result: python queue to put result in
+ @param q_error: python queue to put error in
+ @return None (isn't evaluated)
+ '''
+ pass
+
+
\ No newline at end of file
Added: pyplusplus_dev/ide/model/etree_extension.py
===================================================================
--- pyplusplus_dev/ide/model/etree_extension.py (rev 0)
+++ pyplusplus_dev/ide/model/etree_extension.py 2007-05-02 14:58:58 UTC (rev 1029)
@@ -0,0 +1,93 @@
+# -*- coding: utf-8 -*-
+# Copyright 2004 Roman Yakovenko.
+# 2007 Alexander Eisenhuth
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+from xml.etree.ElementTree import ElementTree
+
+class ElNotFound(Exception):
+ '''
+ Exception element not found
+ '''
+ pass
+
+class AttribNotFound(Exception):
+ '''
+ Execption attribute not found
+ '''
+ pass
+
+class XmlElFinder:
+ '''
+ Find a element in a Tree (xml.etree.ElementTree)
+ '''
+ def __init__(self, root_el):
+ self._root = root_el # Must be of typ xml.etree.ElementTree
+ self._finder = None
+
+ def get_obj(self, element_text):
+ '''
+ Find and return XML element object (Element)
+ @param element_text: Textual description of element to find. Hirarchie
+ is seperated by '.' Ex.: 'rootNode.childNode.element'
+ @return: Element object
+ '''
+
+ child_el = None
+ self._finder = self._root
+
+ for el_name in element_text.split("."):
+ child_el = self._finder.find(el_name)
+
+ # Child not found
+ if child_el == None:
+ raise ElNotFound, "Cannot find Element %s in %s" % \
+ (el_name, element_text)
+
+ self._finder = ElementTree(child_el)
+
+ return child_el
+
+class XmlAttribFinder:
+ '''Find a attribute in a Tree (xml.etree.ElementTree)'''
+ def __init__(self, root_el):
+ self._el_finder = XmlElFinder(root_el)
+
+ def get_obj(self, attrib_text):
+ '''
+ Find and return attribute as tuple
+ @param attrib_text: Textual description of attribute to find. Hirarchie
+ is seperated by '.' Ex.: 'rootNode.childNode.element.attrib1'
+ @return: (<allAttribDict>, <relatedAttribName>) This means a tuple
+ cintaining all attributes of parent element and name of attribute.
+ '''
+ el_text = attrib_text[0 : attrib_text.rfind(".")]
+ attrib_name = attrib_text[attrib_text.rfind(".") + 1 : ]
+ element = self._el_finder.get_obj(el_text)
+ return (element.attrib, attrib_name)
+
+ def get_val(self, attrib_text):
+ '''
+ Find and return attribute value
+ @param attrib_text: Textual description of attribute to find. Hirarchie
+ is seperated by '.' Ex.: 'rootNode.childNode.element.attrib1'
+ @return Attribute value
+ '''
+ attrib_value = None
+
+ el_text = attrib_text[0 : attrib_text.rfind(".")]
+ attrib_name = attrib_text[attrib_text.rfind(".") + 1 : ]
+ element = self._el_finder.get_obj(el_text)
+
+ try:
+ attrib_value = element.attrib[attrib_name]
+
+ except KeyError:
+ raise AttribNotFound, "Cannot find attribute '%s' in element '%s'" \
+ % (attrib_name, el_text)
+
+ return attrib_value
+
+
+
\ No newline at end of file
Added: pyplusplus_dev/ide/model/settings.py
===================================================================
--- pyplusplus_dev/ide/model/settings.py (rev 0)
+++ pyplusplus_dev/ide/model/settings.py 2007-05-02 14:58:58 UTC (rev 1029)
@@ -0,0 +1,383 @@
+# -*- coding: utf-8 -*-
+# Copyright 2004 Roman Yakovenko.
+# 2007 Alexander Eisenhuth
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+'''
+This module contains classes for settings and parameters
+'''
+from model.etree_extension import XmlAttribFinder
+from shutil import copyfile
+# Python 2.5
+from xml.etree.ElementTree import ElementTree
+import os
+import wx
+
+class BaseSettings:
+ '''
+ Base class for settings as a collection of parameters
+ '''
+ def __init__(self, ide_ui, param_obj):
+ self._file_name = None # filename of settings
+ self._ide_ui = ide_ui
+ self._param_obj = param_obj
+
+ def set_changed(self):
+ '''
+ Inform, that any parameter has changed
+ '''
+ self._changed = True
+
+ def get_changed(self):
+ '''
+ Access changed information
+ '''
+ return self._changed
+
+ def get_file_name(self):
+ '''
+ Return file path of settings
+ '''
+ return self._file_name
+
+ def get_param(self, xml_attrib_name):
+ '''
+ Return parameter as string
+ @param xml_attrib_name: Name of parameter
+ '''
+
+ ide_ui = self._ide_ui #@UnusedVariable
+ param_obj = self._param_obj #@UnusedVariable
+
+ for cur_name, rel_obj_str in self._param_list:
+ if cur_name == xml_attrib_name:
+ param = ParameterAccess(eval(rel_obj_str))
+ return param.get_related_object_value()
+
+ raise RuntimeError, "Parameter:%s not defined" % xml_attrib_name
+
+ def _load(self, file_name):#@UnusedVariable
+ '''
+ Load settings from given file
+ @param file_name: path of file. Format is XML.
+ @param ide_ui: wxPython ctrl of ide
+ @param param_obj: object holding parameters
+ '''
+ self._file_name = file_name
+
+ ide_ui = self._ide_ui #@UnusedVariable
+ param_obj = self._param_obj #@UnusedVariable
+
+ root_element = ElementTree(file=file_name).getroot()
+ attrib_finder = XmlAttribFinder(root_element)
+
+ # Loop through our parameter list
+ for xml_attrib_name, rel_obj_str in self._param_list:
+ # In eval we need ide_ui and param_obj
+ # print "XML:%s obj_str:%s" % (xml_attrib_name, rel_obj_str)
+ param = ParameterAccess(eval(rel_obj_str))
+ attrib_val = attrib_finder.get_val(xml_attrib_name)
+ param.update_related_object(attrib_val)
+
+ def _save(self, file_name):
+ '''
+ Save settings into the given file
+ @param file_name: path of file. Format is XML.
+ @param ide_ui: wxPython ctrl of ide
+ @param param_obj: object holding parameters
+ '''
+
+ self._file_name = file_name
+
+ ide_ui = self._ide_ui #@UnusedVariable
+ param_obj = self._param_obj #@UnusedVariable
+
+ etree = ElementTree(file=file_name)
+ root_element = etree.getroot()
+
+ attrib_finder = XmlAttribFinder(root_element)
+
+ for xml_attrib_name, rel_obj_str in self._param_list:
+ # In eval we need ide_ui and param_obj
+ param = ParameterAccess(eval(rel_obj_str))
+ attrib, attrib_key = attrib_finder.get_obj(xml_attrib_name)
+ attrib[attrib_key] = param.get_related_object_value()
+
+ # Write XML-File
+ etree.write(file_name)
+
+ self._changed = False
+
+
+class IdeSettings(BaseSettings):
+ '''
+ Abstracts the settings of the ide
+ '''
+ def __init__(self, ide_ui, param_obj):
+
+ self._param_list = [
+ ('project.maxNumInMenue',
+ 'param_obj.max_num_recent_projects'),
+
+ ('project.recentProjects',
+ 'param_obj.recent_prj_list'),
+
+ ('project.lastPrjPath',
+ 'param_obj.last_prj_path'),
+
+ ('project.lastIncPath',
+ 'param_obj.last_inc_path')
+
+ ]
+
+ BaseSettings.__init__(self, ide_ui, param_obj)
+
+ def load(self):
+ '''
+ Load ide settings
+ '''
+ ide_file_name = self._get_ide_file_name()
+ self._load(ide_file_name)
+
+ def save(self):
+ '''
+ Save settings
+
+ '''
+ ide_file_name = self._get_ide_file_name()
+ self._save(ide_file_name)
+
+ def _get_ide_file_name(self):
+ '''
+ Get the file name of the ide settings filE. If the file doesen't exist
+ we copy a template fiel into the location
+ @param file_path: File path to check
+ '''
+ try:
+ home_dir = os.environ['HOME']
+ except KeyError:
+ home_dir = os.getcwd()
+
+ file_path = os.path.join(home_dir, self._ide_file_name )
+
+ if not os.path.exists(file_path):
+ print "File copied !!"
+ copyfile(self._ide_template_path, file_path)
+
+ return file_path
+
+ # Project template file
+ _ide_template_path = "./IdeTemplate.xml"
+ _ide_file_name = ".pyplusplus_ide"
+
+class ProjectSettings(BaseSettings):
+ '''
+ Abstracts the settings of a project
+ '''
+ def __init__(self, ide_ui, param_obj):
+
+ BaseSettings.__init__(self, ide_ui, param_obj)
+
+ # This list contains tuples of ui elements and the related
+ # attribute of the project file
+ self._param_list = [
+ ('gccXmlSettings.headerPath',
+ 'ide_ui.textHeader'),
+
+ ('gccXmlSettings.gccXmlPath',
+ 'ide_ui.textGccXml'),
+
+ ('gccXmlSettings.includePathList',
+ 'ide_ui.listIncludes'),
+
+ ('gccXmlSettings.macroList',
+ 'ide_ui.listMacros'),
+
+ ('guiGeometry.size',
+ 'ide_ui'),
+
+ ('guiGeometry.horizontalSplitter',
+ 'ide_ui.splitterHorizontal'),
+
+ ('guiGeometry.verticalSplitter',
+ 'ide_ui.splitterVertical')
+ ]
+
+ self._changed = False
+
+ def load(self, file_name):
+ '''
+ Load settings from given file
+ @param file_name: path of file. Format is XML.
+ '''
+ self._load(file_name)
+
+ def save(self, file_name):
+ '''
+ Save settings into the given file
+ @param file_name: path of file. Format is XML.
+ '''
+ # Assert new prj file
+ self._assert_prj_file(file_name)
+ self._save(file_name)
+
+ def _assert_prj_file(self, file_path):
+ '''
+ Assert that the given file exists. If not we copy the template
+ @param file_path: File path to check
+ '''
+ if not os.path.exists(file_path):
+ copyfile(self._prj_template_path, file_path)
+
+ # Project template file
+ _prj_template_path = "./ProjectTemplate.xml"
+
+class ParameterContainer:
+ '''
+ Abstracts one parameter with getter and setter
+ '''
+ def __init__(self, p_type, init_val=None):
+ self._type = p_type
+ self._val = init_val
+
+ def set(self, val):
+ '''
+ Set the related parameter
+ @param val: new value
+ '''
+ self._val = self._type(val)
+
+ def get(self):
+ '''
+ Get the related parameter
+ '''
+
+ return self._val
+
+ def get_type(self):
+ '''
+ Get the (python) type of the parameter
+ '''
+ return self._type
+
+
+class ParameterAccess:
+ '''
+ Abstracts the access (setting and getting) of a parameter. This class
+ has knowledge of wxPython controls (and know how to handle them).
+ Currently we support:
+ - wxTextCtrl
+ - wxListCtrl
+ - wxFrame
+ - wxSplitterWindow
+ - ParameterContainer
+ '''
+ def __init__(self, related_object):
+ self._rel_obj = related_object
+
+ def update_related_object(self, param_value):
+ '''
+ Set the value of the related object with given param_value
+ @param param_value: parameter value to use
+ '''
+
+ #print ">>> rel obj:", self._rel_obj, "val:", param_value
+
+ # Handle wxTextCtrl
+ if isinstance(self._rel_obj, wx.TextCtrl):
+ # We need a string
+ str_param_value = str(param_value)
+ self._rel_obj.SetValue(str_param_value)
+
+ # Handle wxListCtrl
+ elif isinstance(self._rel_obj, wx.ListCtrl):
+ list_param_value = eval(param_value)
+ assert(isinstance(list_param_value, list))
+ cur_num = 0
+ for list_el in list_param_value:
+ self._rel_obj.InsertStringItem(cur_num, list_el)
+ cur_num += 1
+
+ # Handle wxFrame
+ elif isinstance(self._rel_obj, wx.Frame):
+ tup_size = eval(param_value)
+ assert(isinstance(tup_size, tuple))
+ x = tup_size[0]
+ y = tup_size[1]
+ wid = tup_size[2]
+ high = tup_size[3]
+ self._rel_obj.SetDimensions(x, y, wid, high)
+
+ # SplitterWindow
+ elif isinstance(self._rel_obj, wx.SplitterWindow):
+ int_sash_pos = int(param_value)
+ self._rel_obj.SetSashPosition(int_sash_pos, True)
+
+ # ParameterContainer
+ elif isinstance(self._rel_obj, ParameterContainer):
+ if self._rel_obj.get_type() == list:
+ eval_param_value = eval(param_value)
+ elif self._rel_obj.get_type() == int:
+ eval_param_value = eval(param_value)
+ elif self._rel_obj.get_type() == str:
+ eval_param_value = param_value
+ elif self._rel_obj.get_type() == unicode:
+ eval_param_value = unicode(param_value)
+ else:
+ raise RuntimeError, "Unupported typ found", \
+ self._rel_obj.get_type()
+
+ cnv_param_val = self._rel_obj.get_type()(eval_param_value)
+ self._rel_obj.set(cnv_param_val)
+
+ else:
+ raise RuntimeError, "Unsupported type %s" % self._rel_obj.__class__
+
+ def get_related_object_value(self):
+ '''
+ Get value of the related object
+ @return value as string
+ '''
+
+ #print ">>>", self._rel_obj
+
+ str_param_value = "Value not specified"
+
+ # Handle wxTextCtrl
+ if isinstance(self._rel_obj, wx.TextCtrl):
+ # We need a string
+ str_param_value = self._rel_obj.GetValue()
+
+ # Handle wxListCtrl
+ elif isinstance(self._rel_obj, wx.ListCtrl):
+
+ list_of_ctrl = []
+
+ for cur_num in range(self._rel_obj.GetItemCount()):
+ list_el = self._rel_obj.GetItemText(cur_num)
+ list_of_ctrl.append(list_el)
+ cur_num += 1
+ str_param_value = str(list_of_ctrl)
+
+ # Handle wxFrame
+ elif isinstance(self._rel_obj, wx.Frame):
+ x,y = self._rel_obj.GetPositionTuple()
+ wid, high = self._rel_obj.GetSizeTuple()
+ dim = (x,y,wid,high)
+ str_param_value = str(dim)
+
+ # SplitterWindow
+ elif isinstance(self._rel_obj, wx.SplitterWindow):
+ sash_pos = self._rel_obj.GetSashPosition()
+ str_param_value = str(sash_pos)
+
+ # Handle ParameterContainer
+ elif isinstance(self._rel_obj, ParameterContainer):
+ str_param_value = str(self._rel_obj.get())
+
+ else:
+ raise RuntimeError, "Unsupported type %s" % self._rel_obj.__class__
+
+ return str_param_value
+
\ No newline at end of file
Added: pyplusplus_dev/ide/test/test_attrib_finder.py
===================================================================
--- pyplusplus_dev/ide/test/test_attrib_finder.py (rev 0)
+++ pyplusplus_dev/ide/test/test_attrib_finder.py 2007-05-02 14:58:58 UTC (rev 1029)
@@ -0,0 +1,41 @@
+import sys
+import unittest
+# Python 2.5
+from xml.etree.ElementTree import ElementTree
+
+if ".." not in sys.path:
+ sys.path.append("..")
+
+from model.etree_extension import XmlAttribFinder, AttribNotFound
+prj_template_file = "../model/ProjectTemplate.xml"
+
+
+class TestAttribFinder(unittest.TestCase):
+
+ def setUp(self):
+ ''' Executed before each test '''
+ self._root_el_prj_file = ElementTree(file=prj_template_file).getroot()
+
+ def test_find(self):
+ '''Test get_val methode with project template'''
+ af_obj = XmlAttribFinder(self._root_el_prj_file)
+
+ header_path = af_obj.get_val('gccXmlSettings.headerPath')
+ self.assertEqual(header_path, "")
+
+ inc_path_list = af_obj.get_val('gccXmlSettings.includePathList')
+ self.assertEqual(eval(inc_path_list), [])
+
+ inc_path_list_obj = af_obj.get_obj('gccXmlSettings.includePathList')
+
+ self.assertTrue(inc_path_list_obj[1], [])
+
+ self.assertRaises(AttribNotFound, af_obj.get_val,
+ ('gccXmlSettings.xxx'))
+
+ def tearDown(self):
+ ''' Executed after each test '''
+ del self._root_el_prj_file
+
+if __name__ == "__main__":
+ unittest.main()
Modified: pyplusplus_dev/ide/views/frame_main.py
===================================================================
--- pyplusplus_dev/ide/views/frame_main.py 2007-05-01 18:06:08 UTC (rev 1028)
+++ pyplusplus_dev/ide/views/frame_main.py 2007-05-02 14:58:58 UTC (rev 1029)
@@ -15,10 +15,10 @@
def create(parent):
return MainFrame(parent)
-[wxID_MAINFRAMEMENUEFILEEXIT, wxID_MAINFRAMEMENUEFILENEW,
- wxID_MAINFRAMEMENUEFILEOPEN, wxID_MAINFRAMEMENUEFILERECENT,
- wxID_MAINFRAMEMENUEFILESAVE,
-] = [wx.NewId() for _init_coll_menueFile_Items in range(5)]
+[wxID_MAINFRAMEMENUEFILEEXIT, wxID_MAINFRAMEMENUEFILEITEMS7,
+ wxID_MAINFRAMEMENUEFILENEW, wxID_MAINFRAMEMENUEFILEOPEN,
+ wxID_MAINFRAMEMENUEFILERECENT, wxID_MAINFRAMEMENUEFILESAVE,
+] = [wx.NewId() for _init_coll_menueFile_Items in range(6)]
[wxID_MAINFRAMEMENUINCLUDESADDINC, wxID_MAINFRAMEMENUINCLUDESITEMS1,
] = [wx.NewId() for _init_coll_menuIncludes_Items in range(2)]
@@ -154,20 +154,24 @@
def _init_coll_menueFile_Items(self, parent):
# generated method, don't edit
- parent.Append(help=u'Create new Project', id=wxID_MAINFRAMEMENUEFILENEW,
- kind=wx.ITEM_NORMAL, text=u'&New Project')
- parent.Append(help=u'Open existing Project',
+ parent.Append(help=u'Create new project with default settings',
+ id=wxID_MAINFRAMEMENUEFILENEW, kind=wx.ITEM_NORMAL,
+ text=u'&New project')
+ parent.Append(help=u'Open existing project',
id=wxID_MAINFRAMEMENUEFILEOPEN, kind=wx.ITEM_NORMAL,
- text=u'&Open Project')
- parent.Append(help=u'Save current Project',
+ text=u'&Open project')
+ parent.Append(help=u'Save current project',
id=wxID_MAINFRAMEMENUEFILESAVE, kind=wx.ITEM_NORMAL,
- text=u'&Save Project')
+ text=u'&Save project')
+ parent.Append(help=u'Save current project under a different filename',
+ id=wxID_MAINFRAMEMENUEFILEITEMS7, kind=wx.ITEM_NORMAL,
+ text=u'S&ave as ...')
parent.AppendSeparator()
- parent.AppendMenu(help=u'Open recently used Project',
- id=wxID_MAINFRAMEMENUEFILERECENT, submenu=wx.Menu(),
- text=u'Recent Projects')
+ parent.AppendMenu(help=u'Open recently used project',
+ id=wxID_MAINFRAMEMENUEFILERECENT, submenu=self.menueRecentPrj,
+ text=u'&Recent projects')
parent.AppendSeparator()
- parent.Append(help='', id=wxID_MAINFRAMEMENUEFILEEXIT,
+ parent.Append(help=u'Exit IDE', id=wxID_MAINFRAMEMENUEFILEEXIT,
kind=wx.ITEM_NORMAL, text=u'&Exit')
self.Bind(wx.EVT_MENU, self.OnMenueFileNewMenu,
id=wxID_MAINFRAMEMENUEFILENEW)
@@ -177,6 +181,10 @@
id=wxID_MAINFRAMEMENUEFILESAVE)
self.Bind(wx.EVT_MENU, self.OnMenueFileExitMenu,
id=wxID_MAINFRAMEMENUEFILEEXIT)
+ self.Bind(wx.EVT_MENU, self.OnMenueFileSaveAsMenu,
+ id=wxID_MAINFRAMEMENUEFILEITEMS7)
+ self.Bind(wx.EVT_MENU, self.OnMenueFileRecentMenu,
+ id=wxID_MAINFRAMEMENUEFILERECENT)
def _init_coll_menuMacros_Items(self, parent):
# generated method, don't edit
@@ -212,13 +220,12 @@
def _init_coll_statusBar_Fields(self, parent):
# generated method, don't edit
- parent.SetFieldsCount(3)
+ parent.SetFieldsCount(2)
- parent.SetStatusText(number=0, text=u'<helptextOrStatus>')
- parent.SetStatusText(number=1, text=u'<parseTime>')
- parent.SetStatusText(number=2, text=u'<compileTime>')
+ parent.SetStatusText(number=0, text=u'')
+ parent.SetStatusText(number=1, text=u'')
- parent.SetStatusWidths([-1, -1, -1])
+ parent.SetStatusWidths([-1, -1])
def _init_sizers(self):
# generated method, don't edit
@@ -278,6 +285,8 @@
self.menuMacros = wx.Menu(title='')
+ self.menueRecentPrj = wx.Menu(title=u'')
+
self._init_coll_menueFile_Items(self.menueFile)
self._init_coll_menuBar_Menus(self.menuBar)
self._init_coll_menuIncludes_Items(self.menuIncludes)
@@ -286,11 +295,12 @@
def _init_ctrls(self, prnt):
# generated method, don't edit
wx.Frame.__init__(self, id=wxID_MAINFRAME, name=u'MainFrame',
- parent=prnt, pos=wx.Point(-3, -3), size=wx.Size(800, 600),
- style=wx.DEFAULT_FRAME_STYLE, title=u'Py++ IDE')
+ parent=prnt, pos=wx.Point(0, 0), size=wx.Size(800, 600),
+ style=wx.DEFAULT_FRAME_STYLE, title=u'Py++ IDE ()')
self._init_utils()
self.SetClientSize(wx.Size(792, 566))
self.SetMenuBar(self.menuBar)
+ self.Bind(wx.EVT_CLOSE, self.OnMainFrameClose)
self.statusBar = wx.StatusBar(id=wxID_MAINFRAMESTATUSBAR,
name=u'statusBar', parent=self, style=0)
@@ -366,7 +376,7 @@
self.textCode = wx.TextCtrl(id=wxID_MAINFRAMETEXTCODE, name=u'textCode',
parent=self.panelNbCode, pos=wx.Point(0, 0), size=wx.Size(730, 0),
style=wx.TE_READONLY | wx.TE_MULTILINE, value=u'')
- self.textCode.SetToolTipString(u'textCtrl2')
+ self.textCode.SetHelpText(u'')
self.panelButtons = wx.Panel(id=wxID_MAINFRAMEPANELBUTTONS,
name=u'panelButtons', parent=self.panelNbCode, pos=wx.Point(156,
@@ -376,6 +386,8 @@
label=u'Generate XML code', name=u'butGenXml',
parent=self.panelButtons, pos=wx.Point(10, 0), size=wx.Size(120,
23), style=0)
+ self.butGenXml.SetToolTipString(u'')
+ self.butGenXml.SetHelpText(u'Help for button')
self.butGenXml.Bind(wx.EVT_BUTTON, self.OnButGenXmlButton,
id=wxID_MAINFRAMEBUTGENXML)
@@ -465,28 +477,34 @@
self._init_sizers()
def __init__(self, parent):
-
+
self.currentItemInclude = None
self.currentItemMacro = None
self._init_ctrls(parent)
- self._setup_ide_ctrls()
- self.splitterVertical.SetSashPosition(300, True)
- self.SetSize((self.GetSize()[0]+1,self.GetSize()[1]+1))
+ self._setup_ide_ctrls()
def OnMenueFileNewMenu(self, event):
+ self._controller.DoProjectNew()
event.Skip()
def OnMenueFileOpenMenu(self, event):
+ self._controller.OpenDlgLoadProject()
event.Skip()
def OnMenueFileSaveMenu(self, event):
+ self._controller.OpenDlgSaveProject()
event.Skip()
+
+ def OnMenueFileSaveAsMenu(self, event):
+ self._controller.OpenDlgSaveProject(new_file=True)
+ event.Skip()
def OnMenueFileRecentMenu(self, event):
event.Skip()
def OnMenueFileExitMenu(self, event):
+ self._controller.ExitIde()
event.Skip()
def OnTextGenCodeRightDown(self, event):
@@ -582,6 +600,17 @@
self.currentItemMacro = None
event.Skip()
+ def OnMenueRecentPrjItems0Menu(self, event):
+ print "OnMenueRecentPrjItems0Menu"
+ event.Skip()
+
+ def OnMainFrameClose(self, event):
+ if not self._controller.ExitIde():
+ return() # Don't close
+ else:
+ event.Skip()
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|