]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/samples/ide/activegrid/tool/ProjectEditor.py
wxHotkeyModifier --> wxKeyModifier
[wxWidgets.git] / wxPython / samples / ide / activegrid / tool / ProjectEditor.py
index cb407d83187dd2d7de4cec6fbe4bd405a013dd53..9934eaade7cc2cb9578ac8eec1fb7bff2624479c 100644 (file)
@@ -20,12 +20,14 @@ from wxPython.lib.rcsizer import RowColSizer
 import time
 import Service
 import sys
-import activegrid.util.xmlmarshaller
+import activegrid.util.xmlutils
 import UICommon
 import Wizard
+import SVNService
 from IDE import ACTIVEGRID_BASE_IDE
 if not ACTIVEGRID_BASE_IDE:
     import ProcessModelEditor
+from SVNService import SVN_INSTALLED
 
 _ = wx.GetTranslation
 
@@ -45,18 +47,12 @@ HALF_SPACE = 5
 #----------------------------------------------------------------------------
 # XML Marshalling Methods
 #----------------------------------------------------------------------------
-LOCAL_TYPE_MAPPING = { "projectmodel"   : "activegrid.tool.ProjectEditor.ProjectModel", }
-
 
 def load(fileObject):
-    xml = fileObject.read()
-    projectModel = activegrid.util.xmlmarshaller.unmarshal(xml, knownTypes=LOCAL_TYPE_MAPPING)
-    return projectModel
-
+    return activegrid.util.xmlutils.defaultLoad(fileObject, knownTypes={"projectmodel" : ProjectModel})
 
 def save(fileObject, projectModel):
-    xml = activegrid.util.xmlmarshaller.marshal(projectModel, prettyPrint=True, knownTypes=LOCAL_TYPE_MAPPING)
-    fileObject.write(xml)
+    activegrid.util.xmlutils.defaultSave(fileObject, projectModel, prettyPrint=True, knownTypes={"projectmodel" : ProjectModel})
 
 
 #----------------------------------------------------------------------------
@@ -70,6 +66,9 @@ class ProjectModel:
 
     def __init__(self):
         self._files = []
+        
+    def initialize(self):
+        pass
      
    
 class ProjectDocument(wx.lib.docview.Document):
@@ -127,6 +126,8 @@ class ProjectDocument(wx.lib.docview.Document):
         for path in paths:
             if path.startswith(curPath):
                 path = "." + path[curPathLen:]  # use relative path
+                if os.sep != '/':
+                    path = path.replace(os.sep, '/', -1)  # always save out with '/' as path separator for cross-platform compatibility.
             else:
                 pass                            # use absolute path
             newFilePaths.append(path)
@@ -139,8 +140,6 @@ class ProjectDocument(wx.lib.docview.Document):
             if path.startswith("."):  # relative to project file
                 curPath = os.path.dirname(self.GetFilename())
                 path = os.path.normpath(os.path.join(curPath, path))
-            elif not ACTIVEGRID_BASE_IDE:
-                print "Warning: absolute path '%s' found in project file, this may affect deployment" % path
             newFilePaths.append(path)
         return newFilePaths
 
@@ -225,7 +224,7 @@ class ProjectDocument(wx.lib.docview.Document):
             if isProject:
                 documents = self.GetDocumentManager().GetDocuments()
                 for document in documents:
-                    if document.GetFilename() == oldFile:  # If the renamed document is open, update it
+                    if os.path.normcase(document.GetFilename()) == os.path.normcase(oldFile):  # If the renamed document is open, update it
                         document.SetFilename(newFile)
                         document.SetTitle(wx.lib.docview.FileNameFromPath(newFile))
                         document.UpdateAllViews(hint = ("rename", document, newFile))
@@ -234,7 +233,7 @@ class ProjectDocument(wx.lib.docview.Document):
                 self.AddFile(newFile)
                 documents = self.GetDocumentManager().GetDocuments()
                 for document in documents:
-                    if document.GetFilename() == oldFile:  # If the renamed document is open, update it
+                    if os.path.normcase(document.GetFilename()) == os.path.normcase(oldFile):  # If the renamed document is open, update it
                         document.SetFilename(newFile, notifyViews = True)
                         document.UpdateAllViews(hint = ("rename", document, newFile))
             return True
@@ -289,7 +288,7 @@ class NewProjectWizard(Wizard.BaseWizard):
                 # What if the document is already open and we're overwriting it?
                 documents = docManager.GetDocuments()
                 for document in documents:
-                    if document.GetFilename() == self._fullProjectPath:  # If the renamed document is open, update it
+                    if os.path.normcase(document.GetFilename()) == os.path.normcase(self._fullProjectPath):  # If the renamed document is open, update it
                         document.DeleteAllViews()
                         break
                 os.remove(self._fullProjectPath)
@@ -844,10 +843,12 @@ class ProjectView(wx.lib.docview.View):
         or id == ProjectService.RENAME_ID
         or id == ProjectService.ADD_FILES_TO_PROJECT_ID
         or id == ProjectService.ADD_ALL_FILES_TO_PROJECT_ID
-        or id == wx.lib.pydocview.FilePropertiesService.PROPERTIES_ID
-        or id == ProjectService.DELETE_FILE_ID):
+        or id == wx.lib.pydocview.FilePropertiesService.PROPERTIES_ID):
             event.Enable(self._HasSelection())
             return True
+        elif id == ProjectService.DELETE_FILE_ID:
+            event.Enable(len(self.GetSelectedFiles()) > 0)
+            return True
         elif id == ProjectService.ADD_CURRENT_FILE_TO_PROJECT_ID:
             event.Enable(False)
             return True
@@ -862,6 +863,10 @@ class ProjectView(wx.lib.docview.View):
         or id == ProjectService.OPEN_SELECTION_ID):
             event.Enable(self._HasFilesSelected())
             return True
+        elif (id == wx.ID_PREVIEW
+        or id == wx.ID_PRINT):
+            event.Enable(False)
+            return True            
         else:
             return False
 
@@ -909,7 +914,26 @@ class ProjectView(wx.lib.docview.View):
     def GetSelectedFile(self):
         for item in self._treeCtrl.GetSelections():
             return self._GetItemFile(item)
+
             
+    def GetSelectedFiles(self):
+        filenames = []
+        for item in self._treeCtrl.GetSelections():
+            filename = self._GetItemFile(item)
+            if filename and filename not in filenames:
+                filenames.append(filename)
+        return filenames
+
+
+    def GetSelectedProjects(self):
+        filenames = []
+        for item in self._treeCtrl.GetSelections():
+            if self._IsItemProject(item):
+                filename = self._treeCtrl.GetLongFilename(item)
+                if filename and filename not in filenames:
+                    filenames.append(filename)
+        return filenames
+
 
     def AddProjectToView(self, document):
         rootItem = self._treeCtrl.GetRootItem()
@@ -927,6 +951,17 @@ class ProjectView(wx.lib.docview.View):
             document.GetCommandProcessor().SetEditMenu(wx.GetApp().GetEditMenu(self._GetParentFrame()))
 
 
+    def HasFocus(self):
+        winWithFocus = wx.Window.FindFocus()
+        if not winWithFocus:
+            return False
+        while winWithFocus:
+            if winWithFocus == self._treeCtrl:
+                return True
+            winWithFocus = winWithFocus.GetParent()
+        return False
+
+
     #----------------------------------------------------------------------------
     # Control events
     #----------------------------------------------------------------------------
@@ -957,8 +992,7 @@ class ProjectView(wx.lib.docview.View):
                         allfilter = allfilter + _(';')
                     descr = descr + temp.GetDescription() + _(" (") + temp.GetFileFilter() + _(") |") + temp.GetFileFilter()  # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
                     allfilter = allfilter + temp.GetFileFilter()
-            descr = _("All") + _(" (") + allfilter + _(") |") + allfilter + _('|') + descr  # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
-            descr = descr + _("|") + _("Any (*.*) | *.*")
+            descr = _("All (%s)|%s|%s|Any (*.*) | *.*") %  (allfilter, allfilter, descr)  # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
         else:
             descr = _("*.*")
             
@@ -980,19 +1014,19 @@ class ProjectView(wx.lib.docview.View):
 
 
     def OnAddDirToProject(self, event):
-        frame = wx.Dialog(None, -1, _("Add All Files from Directory to Project"), size= (320,200))
-        borderSizer = wx.BoxSizer(wx.HORIZONTAL)
-
+        frame = wx.Dialog(None, -1, _("Add Directory Files to Project"), size= (320,200))
         contentSizer = wx.BoxSizer(wx.VERTICAL)
+        
+        flexGridSizer = wx.FlexGridSizer(cols = 2, vgap=HALF_SPACE, hgap=HALF_SPACE)
+        flexGridSizer.Add(wx.StaticText(frame, -1, _("Directory:")), 0, wx.ALIGN_CENTER_VERTICAL, 0)
         lineSizer = wx.BoxSizer(wx.HORIZONTAL)
-        lineSizer.Add(wx.StaticText(frame, -1, _("Directory:")), 0, wx.ALIGN_CENTER | wx.RIGHT, HALF_SPACE)
-        dirCtrl = wx.TextCtrl(frame, -1, os.path.dirname(self.GetDocument().GetFilename()), size=(200,-1))
+        dirCtrl = wx.TextCtrl(frame, -1, os.path.dirname(self.GetDocument().GetFilename()), size=(250,-1))
         dirCtrl.SetToolTipString(dirCtrl.GetValue())
-        lineSizer.Add(dirCtrl, 0, wx.LEFT, HALF_SPACE)
-        findDirButton = wx.Button(frame, -1, "Browse...")
-        lineSizer.Add(findDirButton, 0, wx.LEFT, HALF_SPACE)
-        contentSizer.Add(lineSizer, 0, wx.BOTTOM, SPACE)
-        
+        lineSizer.Add(dirCtrl, 1, wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
+        findDirButton = wx.Button(frame, -1, _("Browse..."))
+        lineSizer.Add(findDirButton, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, HALF_SPACE)
+        flexGridSizer.Add(lineSizer, 1, wx.EXPAND)
+                
         def OnBrowseButton(event):
             dlg = wx.DirDialog(frame, _("Choose a directory:"), style=wx.DD_DEFAULT_STYLE)
             dir = dirCtrl.GetValue()
@@ -1021,29 +1055,28 @@ class ProjectView(wx.lib.docview.View):
             descr = template.GetDescription() + _(" (") + template.GetFileFilter() + _(")")
             choices.append(descr)
             allfilter = allfilter + template.GetFileFilter()
-        choices.insert(0, _("All (%s)") % allfilter)
-        filterChoice = wx.Choice(frame, -1, size=(210, -1), choices=choices)
+        choices.insert(0, _("All (%s)") % allfilter)  # first item
+        choices.append(_("Any (*.*)"))  # last item
+        filterChoice = wx.Choice(frame, -1, size=(250, -1), choices=choices)
         filterChoice.SetSelection(0)
         filterChoice.SetToolTipString(_("Select file type filter."))
-        lineSizer = wx.BoxSizer(wx.HORIZONTAL)
-        lineSizer.Add(wx.StaticText(frame, -1, _("Files of type:")), 0, wx.ALIGN_CENTER | wx.RIGHT, HALF_SPACE)
-        lineSizer.Add(filterChoice, 1, wx.LEFT, HALF_SPACE)
-        contentSizer.Add(lineSizer, 0, wx.BOTTOM|wx.EXPAND, SPACE)
+        flexGridSizer.Add(wx.StaticText(frame, -1, _("Files of type:")), 0, wx.ALIGN_CENTER_VERTICAL)
+        flexGridSizer.Add(filterChoice, 1, wx.EXPAND)
+        
+        contentSizer.Add(flexGridSizer, 0, wx.ALL|wx.EXPAND, SPACE)
         
         subfolderCtrl = wx.CheckBox(frame, -1, _("Add files from subdirectories"))
         subfolderCtrl.SetValue(True)
-        contentSizer.Add(subfolderCtrl, 0, wx.BOTTOM, SPACE)
+        contentSizer.Add(subfolderCtrl, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, SPACE)
 
-        borderSizer.Add(contentSizer, 0, wx.TOP|wx.BOTTOM|wx.LEFT, SPACE)
-
-        buttonSizer = wx.BoxSizer(wx.VERTICAL)
+        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
         findBtn = wx.Button(frame, wx.ID_OK, _("Add"))
         findBtn.SetDefault()
-        buttonSizer.Add(findBtn, 0, wx.BOTTOM, HALF_SPACE)
+        buttonSizer.Add(findBtn, 0, wx.RIGHT, HALF_SPACE)
         buttonSizer.Add(wx.Button(frame, wx.ID_CANCEL), 0)
-        borderSizer.Add(buttonSizer, 0, wx.ALL, SPACE)
+        contentSizer.Add(buttonSizer, 0, wx.ALL|wx.ALIGN_RIGHT, SPACE)
 
-        frame.SetSizer(borderSizer)
+        frame.SetSizer(contentSizer)
         frame.Fit()
 
         status = frame.ShowModal()
@@ -1080,7 +1113,8 @@ class ProjectView(wx.lib.docview.View):
                 paths = []
                 
                 index = filterChoice.GetSelection()
-                if index:
+                lastIndex = filterChoice.GetCount()-1
+                if index and index != lastIndex:  # if not All or Any
                     template = visibleTemplates[index-1]
 
                 # do search in files on disk
@@ -1089,7 +1123,7 @@ class ProjectView(wx.lib.docview.View):
                         break
                         
                     for name in files:
-                        if index == 0:  # all
+                        if index == 0:  # All
                             for template in visibleTemplates:
                                 if template.FileMatchesTemplate(name):
                                     filename = os.path.join(root, name)
@@ -1100,6 +1134,11 @@ class ProjectView(wx.lib.docview.View):
 
                                     paths.append(filename)
                                     break
+                        elif index == lastIndex:  # Any
+                            filename = os.path.join(root, name)
+                            # if already in project, don't add it, otherwise undo will remove it from project even though it was already in it.
+                            if not doc.IsFileInProject(filename):
+                                paths.append(filename)                    
                         else:  # use selected filter
                             if template.FileMatchesTemplate(name):
                                 filename = os.path.join(root, name)
@@ -1180,7 +1219,12 @@ class ProjectView(wx.lib.docview.View):
         else:  # Project context
             itemIDs = [wx.ID_CLOSE, wx.ID_SAVE, wx.ID_SAVEAS, None]
         menuBar = self._GetParentFrame().GetMenuBar()
-        itemIDs = itemIDs + [ProjectService.ADD_FILES_TO_PROJECT_ID, ProjectService.ADD_ALL_FILES_TO_PROJECT_ID, ProjectService.REMOVE_FROM_PROJECT, None, wx.ID_UNDO, wx.ID_REDO, None, wx.ID_CUT, wx.ID_COPY, wx.ID_PASTE, wx.ID_CLEAR, None, wx.ID_SELECTALL, ProjectService.RENAME_ID, ProjectService.DELETE_FILE_ID, None, wx.lib.pydocview.FilePropertiesService.PROPERTIES_ID]
+        itemIDs = itemIDs + [ProjectService.ADD_FILES_TO_PROJECT_ID, ProjectService.ADD_ALL_FILES_TO_PROJECT_ID, ProjectService.REMOVE_FROM_PROJECT]
+        svnIDs = [SVNService.SVNService.SVN_UPDATE_ID, SVNService.SVNService.SVN_CHECKIN_ID, SVNService.SVNService.SVN_REVERT_ID]
+        if SVN_INSTALLED:
+            itemIDs = itemIDs + [None, SVNService.SVNService.SVN_UPDATE_ID, SVNService.SVNService.SVN_CHECKIN_ID, SVNService.SVNService.SVN_REVERT_ID]
+        globalIDs = [wx.ID_UNDO, wx.ID_REDO, wx.ID_CLOSE, wx.ID_SAVE, wx.ID_SAVEAS]
+        itemIDs = itemIDs + [None, wx.ID_UNDO, wx.ID_REDO, None, wx.ID_CUT, wx.ID_COPY, wx.ID_PASTE, wx.ID_CLEAR, None, wx.ID_SELECTALL, ProjectService.RENAME_ID, ProjectService.DELETE_FILE_ID, None, wx.lib.pydocview.FilePropertiesService.PROPERTIES_ID]
         for itemID in itemIDs:
             if not itemID:
                 menu.AppendSeparator()
@@ -1193,8 +1237,16 @@ class ProjectView(wx.lib.docview.View):
                     wx.EVT_MENU(self._GetParentFrame(), ProjectService.REMOVE_FROM_PROJECT, self.OnClear)
                     wx.EVT_UPDATE_UI(self._GetParentFrame(), ProjectService.REMOVE_FROM_PROJECT, self._GetParentFrame().ProcessUpdateUIEvent)
                 else:
+                    svnService = wx.GetApp().GetService(SVNService.SVNService)
                     item = menuBar.FindItemById(itemID)
                     if item:
+                        if itemID in svnIDs:
+                            if SVN_INSTALLED and svnService:
+                                wx.EVT_MENU(self._GetParentFrame(), itemID, svnService.ProcessEvent)
+                        elif itemID in globalIDs:
+                            pass
+                        else:
+                            wx.EVT_MENU(self._treeCtrl, itemID, self.ProcessEvent)
                         menu.Append(itemID, item.GetLabel())
         self._treeCtrl.PopupMenu(menu, wx.Point(event.GetX(), event.GetY()))
         menu.Destroy()
@@ -1386,8 +1438,9 @@ class ProjectView(wx.lib.docview.View):
                         findFile.Destroy()
                         if newpath:
                             # update Project Model with new location
-                            self.GetDocument().RemoveFile(filepath)
-                            self.GetDocument().AddFile(newpath)
+                            project = self._GetItemProject(item)
+                            project.RemoveFile(filepath)
+                            project.AddFile(newpath)
                             filepath = newpath
 
                     doc = self.GetDocumentManager().CreateDocument(filepath, wx.lib.docview.DOC_SILENT)
@@ -1497,7 +1550,7 @@ class ProjectView(wx.lib.docview.View):
                 else:
                     if self._treeCtrl.GetLongFilename(child) == longFileName:
                         return child
-                (child, cookie2) = self._treeCtrl.GetNextChild(project, cookie)
+                (child, cookie2) = self._treeCtrl.GetNextChild(project, cookie2)
             (project, cookie) = self._treeCtrl.GetNextChild(rootItem, cookie)
         return None
 
@@ -1616,9 +1669,8 @@ class ProjectPropertiesDialog(wx.Dialog):
         sizer.Add(notebook, 0, wx.ALL | wx.EXPAND, SPACE)
         sizer.Add(self.CreateButtonSizer(wx.OK), 0, wx.ALIGN_RIGHT | wx.RIGHT | wx.BOTTOM, HALF_SPACE)
 
-        sizer.Fit(self)
-        self.SetDimensions(-1, -1, 310, -1, wx.SIZE_USE_EXISTING)
         self.SetSizer(sizer)
+        sizer.Fit(self)
         self.Layout()
 
 
@@ -1744,7 +1796,7 @@ class ProjectService(Service.Service):
                 wx.EVT_MENU(frame, ProjectService.ADD_FILES_TO_PROJECT_ID, frame.ProcessEvent)
                 wx.EVT_UPDATE_UI(frame, ProjectService.ADD_FILES_TO_PROJECT_ID, frame.ProcessUpdateUIEvent)
             if not menuBar.FindItemById(ProjectService.ADD_ALL_FILES_TO_PROJECT_ID):
-                projectMenu.Append(ProjectService.ADD_ALL_FILES_TO_PROJECT_ID, _("Add All Files to Project..."), _("Adds a directory's documents to the current project"))
+                projectMenu.Append(ProjectService.ADD_ALL_FILES_TO_PROJECT_ID, _("Add Directory Files to Project..."), _("Adds a directory's documents to the current project"))
                 wx.EVT_MENU(frame, ProjectService.ADD_ALL_FILES_TO_PROJECT_ID, frame.ProcessEvent)
                 wx.EVT_UPDATE_UI(frame, ProjectService.ADD_ALL_FILES_TO_PROJECT_ID, frame.ProcessUpdateUIEvent)
             if not menuBar.FindItemById(ProjectService.ADD_CURRENT_FILE_TO_PROJECT_ID):
@@ -1799,9 +1851,43 @@ class ProjectService(Service.Service):
 
     def ProcessEventBeforeWindows(self, event):
         id = event.GetId()
+        
         if id == wx.ID_CLOSE_ALL:
             self.OnFileCloseAll(event)
             return True
+            
+        elif id == wx.ID_CLOSE:
+            document = self.GetDocumentManager().GetCurrentDocument()
+            if document and document.GetDocumentTemplate().GetDocumentType() == ProjectDocument:
+                self.OnProjectClose(event)
+                return True
+            else:
+                return False
+        return False
+
+
+    def ProcessUpdateUIEventBeforeWindows(self, event):
+        id = event.GetId()
+        
+        if id == wx.ID_CLOSE_ALL:
+            for document in self.GetDocumentManager().GetDocuments():
+                if document.GetDocumentTemplate().GetDocumentType() != ProjectDocument:
+                    event.Enable(True)
+                    return True
+                    
+            event.Enable(False)
+            return True
+            
+        elif id == wx.ID_CLOSE:
+            document = self.GetDocumentManager().GetCurrentDocument()
+            if document and document.GetDocumentTemplate().GetDocumentType() == ProjectDocument:
+                projectFilenames = self.GetView().GetSelectedProjects()
+                if projectFilenames and len(projectFilenames):
+                    event.Enable(True)
+                else:
+                    event.Enable(False)
+                return True
+                
         return False
 
 
@@ -2030,6 +2116,14 @@ class ProjectService(Service.Service):
         self.GetView().Activate(True)  # after add, should put focus on project editor
 
 
+    def OnProjectClose(self, event):
+        projectFilenames = self.GetView().GetSelectedProjects()
+        for filename in projectFilenames:
+            doc = self.FindProjectByFile(filename)
+            if doc:
+                self.GetDocumentManager().CloseDocument(doc, False)
+
+
     def OnFileCloseAll(self, event):
         for document in self.GetDocumentManager().GetDocuments()[:]:  # Cloning list to make sure we go through all docs even as they are deleted
             if document.GetDocumentTemplate().GetDocumentType() != ProjectDocument: