+    def OnAddDirToProject(self, event):
+        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)
+        dirCtrl = wx.TextCtrl(frame, -1, os.path.dirname(self.GetDocument().GetFilename()), size=(250,-1))
+        dirCtrl.SetToolTipString(dirCtrl.GetValue())
+        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()
+            if len(dir):
+                dlg.SetPath(dir)
+            if dlg.ShowModal() == wx.ID_OK:
+                dirCtrl.SetValue(dlg.GetPath())
+                dirCtrl.SetToolTipString(dirCtrl.GetValue())
+                dirCtrl.SetInsertionPointEnd()
+
+            dlg.Destroy()
+        wx.EVT_BUTTON(findDirButton, -1, OnBrowseButton)
+
+        visibleTemplates = []
+        for template in self.GetDocumentManager()._templates:
+            if template.IsVisible():
+                visibleTemplates.append(template)
+                
+        choices = []
+        allfilter = ''
+        descr = ''
+        for template in visibleTemplates:
+            if len(descr) > 0:
+                descr = descr + _('|')
+                allfilter = allfilter + _(';')
+            descr = template.GetDescription() + _(" (") + template.GetFileFilter() + _(")")
+            choices.append(descr)
+            allfilter = allfilter + template.GetFileFilter()
+        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."))
+        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.LEFT|wx.ALIGN_CENTER_VERTICAL, SPACE)
+
+        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
+        findBtn = wx.Button(frame, wx.ID_OK, _("Add"))
+        findBtn.SetDefault()
+        buttonSizer.Add(findBtn, 0, wx.RIGHT, HALF_SPACE)
+        buttonSizer.Add(wx.Button(frame, wx.ID_CANCEL), 0)
+        contentSizer.Add(buttonSizer, 0, wx.ALL|wx.ALIGN_RIGHT, SPACE)
+
+        frame.SetSizer(contentSizer)
+        frame.Fit()
+
+        status = frame.ShowModal()
+
+        passedCheck = False
+        while status == wx.ID_OK and not passedCheck:
+            if not os.path.exists(dirCtrl.GetValue()):
+                dlg = wx.MessageDialog(frame,
+                                       _("'%s' does not exist.") % dirCtrl.GetValue(),
+                                       _("Find in Directory"),
+                                       wx.OK | wx.ICON_EXCLAMATION
+                                       )
+                dlg.ShowModal()
+                dlg.Destroy()
+
+                status = frame.ShowModal()
+            else:
+                passedCheck = True
+            
+        if status == wx.ID_OK:            
+            frame.Destroy()
+
+            wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
+            
+            doc = self.GetDocument()
+            searchSubfolders = subfolderCtrl.IsChecked()
+            dirString = dirCtrl.GetValue()
+            
+            if os.path.isfile(dirString):
+                # If they pick a file explicitly, we won't prevent them from adding it even if it doesn't match the filter.
+                # We'll assume they know what they're doing.
+                paths = [dirString]
+            else:
+                paths = []
+                
+                index = filterChoice.GetSelection()
+                lastIndex = filterChoice.GetCount()-1
+                if index and index != lastIndex:  # if not All or Any
+                    template = visibleTemplates[index-1]
+
+                # do search in files on disk
+                for root, dirs, files in os.walk(dirString):
+                    if not searchSubfolders and root != dirString:
+                        break
+                        
+                    for name in files:
+                        if index == 0:  # All
+                            for template in visibleTemplates:
+                                if template.FileMatchesTemplate(name):
+                                    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 doc.IsFileInProject(filename):
+                                        break
+
+                                    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)
+                                # 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)                    
+    
+            wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
+
+            doc.GetCommandProcessor().Submit(ProjectAddFilesCommand(doc, paths))
+            self.Activate(True)  # after add, should put focus on project editor
+        else:
+            frame.Destroy()
+
+