Controllers.py :  » IDE » Boa-Constructor » boa-constructor-0.6.1 » Models » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » IDE » Boa Constructor 
Boa Constructor » boa constructor 0.6.1 » Models » Controllers.py
#-----------------------------------------------------------------------------
# Name:        Controllers.py
# Purpose:     Controller classes for the MVC pattern
#
# Author:      Riaan Booysen
#
# Created:     2001/13/08
# RCS-ID:      $Id: Controllers.py,v 1.16 2007/07/02 15:01:11 riaan Exp $
# Copyright:   (c) 2001 - 2007 Riaan Booysen
# Licence:     GPL
#-----------------------------------------------------------------------------
print 'importing Models.Controllers'

import os, codecs

import wx

import Preferences, Utils
from Preferences import keyDefs,IS
from Utils import _

import EditorHelper, PaletteStore, EditorModels

from Views import EditorViews,SourceViews,DiffView

from Explorers import ExplorerNodes

addTool = Utils.AddToolButtonBmpIS


class BaseEditorController:
    """ Between user and model operations

    Provides interface to add new and open existing models
    Manages toolbar and menu actions
    Custom classes should define Model operations as events
    """
    docked = True

    Model           = None
    DefaultViews    = []
    AdditionalViews = []

    plugins = ()

    def __init__(self, editor):
        self.editor = editor
        self.evts = []

        self.plugins = [Plugin(self) for Plugin in self.plugins]

    def getModel(self):
        return self.editor.getActiveModulePage().model

    def createModel(self, source, filename, name, editor, saved, modelParent=None):
        pass

    def createNewModel(self, modelParent=None):
        pass

    def afterAddModulePage(self, model):
        pass

    def newFileTransport(self, name, filename):
        from Explorers.FileExplorer import FileSysNode
        return FileSysNode(name, filename, None, -1, None, None, properties = {})

    def addEvt(self, wId, meth):
        self.editor.Bind(wx.EVT_MENU, meth, id=wId)
        self.evts.append(wId)

    def disconnectEvts(self):
        for wId in self.evts:
            self.editor.Disconnect(wId)
        self.evts = []

    def addMenu(self, menu, wId, label, accls, code=(), bmp=''):
        Utils.appendMenuItem(menu, wId, label, code, bmp)
        if code:
            accls.append( (code[0], code[1], wId) )

#-------------------------------------------------------------------------------
    def actions(self, model):
        """ Override to define Controller/Model actions

        Should return a list of tuples in this form:
        [('Name', self.OnEvent, 'BmpPath', 'KeyDef'), ...]
        """
        return []

    def addActions(self, toolbar, menu, model):
        actions = self.actions(model)
        for plugin in self.plugins:
            actions.extend(plugin.actions(model))

        accls = []

        for name, event, bmp, key in actions:
            if name != '-':
                wId = wx.NewId()
                self.addEvt(wId, event)
                if key: code = keyDefs[key]
                else:   code = ()
                self.addMenu(menu, wId, name, accls, code, bmp)
            else:
                menu.AppendSeparator()

            if bmp:
                if bmp != '-':
                    addTool(self.editor, toolbar, bmp, name, event)
                elif name == '-' and bmp == '-':
                    toolbar.AddSeparator()

        return accls


class EditorController(BaseEditorController):
    closeBmp = 'Images/Editor/Close.png'

    def actions(self, model):
        return BaseEditorController.actions(self, model) + \
               [(_('Close'), self.OnClose, self.closeBmp, 'Close')]

    def OnClose(self, event):
        self.editor.closeModulePage(self.editor.getActiveModulePage())

class PersistentController(EditorController):
    saveBmp = 'Images/Editor/Save.png'
    saveAsBmp = 'Images/Editor/SaveAs.png'

    def actions(self, model):
        return EditorController.actions(self, model) + \
               [(_('Reload'), self.OnReload, '-', ''),
                (_('Save'), self.OnSave, self.saveBmp, 'Save'),
                (_('Save as...'), self.OnSaveAs, self.saveAsBmp, 'SaveAs'),
                ('-', None, '', ''),
                (_('Toggle read-only'), self.OnToggleReadOnly, '-', ''),
                (_('NDiff files...'), self.OnNDiffFile, '-', '')]

    def createModel(self, source, filename, main, saved, modelParent=None):
        return self.Model(source, filename, self.editor, saved)

    def createNewModel(self, modelParent=None):
        name = self.editor.getValidName(self.Model)
        model = self.createModel('', name, '', False)
        model.transport = self.newFileTransport('', name)
        model.new()

        return model, name

    def checkUnsaved(self, model, checkModified=False):
        if not model.savedAs or checkModified and (model.modified or \
              len(model.viewsModified)):
            wx.LogError(_('Cannot perform this action on an unsaved%s module')%(
                  checkModified and '/modified' or '') )
            return True
        else:
            return False

    def OnSave(self, event):
        try:
            self.editor.activeModSaveOrSaveAs()
        except ExplorerNodes.TransportModifiedSaveError, err:
            errStr = err.args[0]
            if errStr == 'Reload':
                self.OnReload(event)
            elif errStr == 'Cancel':
                pass
            else:
                wx.LogError(str(err))
        except ExplorerNodes.TransportSaveError, err:
            wx.LogError(str(err))

    def OnSaveAs(self, event):
        try:
            self.editor.activeModSaveOrSaveAs(forceSaveAs=True)
        except ExplorerNodes.TransportModifiedSaveError, err:
            errStr = err.args[0]
            if errStr == 'Reload':
                self.OnReload(event)
            elif errStr == 'Cancel':
                pass
            else:
                wx.LogError(str(err))
        except ExplorerNodes.TransportSaveError, err:
            wx.LogError(str(err))

    def OnReload(self, event):
        model = self.getModel()
        if model:
            if not model.savedAs:
                wx.MessageBox(_('Cannot reload, this file has not been saved yet.'),
                             _('Reload'), wx.OK | wx.ICON_ERROR)
                return

            if model.hasUnsavedChanges() and \
                  wx.MessageBox(_('There are unsaved changes.\n'\
                                  'Are you sure you want to reload?'),
                                _('Confirm reload'), wx.YES_NO | wx.ICON_WARNING) != wx.YES:
                return
            try:
                model.load()

                self.editor.updateModuleState(model)
            except ExplorerNodes.TransportLoadError, error:
                wx.LogError(str(error))

    def OnToggleReadOnly(self, event):
        model = self.getModel()
        if model and model.transport and model.transport.stdAttrs.has_key('read-only'):
            model.transport.updateStdAttrs()
            ro = model.transport.stdAttrs['read-only']
            model.transport.setStdAttr('read-only', not ro)

            if model.views.has_key('Source'):
                model.views['Source'].updateFromAttrs()

            self.editor.updateModuleState(model)
        else:
            wx.LogError(_('Read-only not supported on this transport'))

    def OnNDiffFile(self, event=None, filename=''):
        model = self.getModel()
        model.refreshFromViews()
        if model:
            if self.checkUnsaved(model): return
            if not filename:
                filename = self.editor.openFileDlg(curfile=os.path.basename(model.filename))
            if filename:
                tbName = 'Diff with : '+filename
                if not model.views.has_key(tbName):
                    resultView = self.editor.addNewView(tbName,
                          DiffView.PythonSourceDiffView)
                else:
                    resultView = model.views[tbName]

                resultView.tabName = tbName
                resultView.diffWith = filename
                resultView.refresh()
                resultView.focus()


class SourceController(PersistentController):
    AdditionalViews = [EditorViews.CVSConflictsView]

    def OnDiffFile(self, event, diffWithFilename=''):
        model = self.getModel()
        if model:
            if self.checkUnsaved(model): return
            if not diffWithFilename:
                diffWithFilename = self.editor.openFileDlg()
            filename = model.assertLocalFile(filename)

    def OnPatchFile(self, event, patchFilename=''):
        model = self.getModel()
        if model:
            if self.checkUnsaved(model): return
            if not patchFilename:
                patchFilename = self.editor.openFileDlg()
            filename = model.assertLocalFile(filename)

class TextController(PersistentController):
    Model           = EditorModels.TextModel
    DefaultViews    = [SourceViews.TextView]
    AdditionalViews = []

class UndockedController(BaseEditorController):
    docked          = False
    def createModel(self, source, filename, main, saved, modelParent=None):
        return self.Model(source, filename, self.editor, saved)

    def display(self, model):
        """ Override to display undocked interface """

class BitmapFileController(UndockedController):
    Model           = EditorModels.BitmapFileModel
    DefaultViews    = []
    AdditionalViews = []

    def display(self, model):
        from ZopeLib import ImageViewer
        ImageViewer.create(self.editor).showImage(model.filename, model.transport)

# XXX move to a new module PythonComControllers
class MakePyController(BaseEditorController):
    docked          = False
    Model           = None
    DefaultViews    = []
    AdditionalViews = []

    def createNewModel(self, modelParent=None):
        return None, None

    def display(self, model):
        import makepydialog
        dlg = makepydialog.create(self.editor)
        try:
            if dlg.ShowModal() == wx.ID_OK and dlg.generatedFilename:
                self.editor.openOrGotoModule(dlg.generatedFilename)
        finally:
            dlg.Destroy()

#-------------------------------------------------------------------------------

def identifyFilename(filename):
    dummy, name = os.path.split(filename)
    base, ext = os.path.splitext(filename)
    lext = ext.lower()

    if fullnameTypes.has_key(name):
        return fullnameTypes[name]
    if not ext and base.upper() == base:
        return EditorModels.TextModel, '', lext
    if EditorHelper.extMap.has_key(lext):
        return EditorHelper.extMap[lext], '', lext
    if lext in EditorHelper.internalFilesReg:
        return EditorModels.InternalFileModel, '', lext
    return None, '', lext

def identifyFile(filename, source=None, localfs=True):
    """ Return appropriate model for given source file.
        Assumes header will be part of the first continious comment block """
    Model, main, lext = identifyFilename(filename)
    if Model is not None:
        return Model, main

    if lext == defaultExt:
        BaseModel = DefaultModel
    else:
        BaseModel = EditorModels.UnknownFileModel

    if source is None and not localfs:
        if lext in EditorHelper.inspectableFilesReg.keys():
            return EditorHelper.inspectableFilesReg[lext], ''
        else:
            return BaseModel, ''
    elif lext in EditorHelper.inspectableFilesReg.keys():
        BaseModel = EditorHelper.inspectableFilesReg[lext]
        if source is not None:
            return identifySource[lext](source.split('\n'))
        elif not Preferences.exInspectInspectableFiles:
            return BaseModel, ''
        if os.path.exists(filename):
            f = open(filename)
            try:
                while 1:
                    line = f.readline()
                    if not line: break
                    line = line.strip()
                    if line.startswith(codecs.BOM_UTF8):
                        line = line[len(codecs.BOM_UTF8):]
                    if line and headerStartChar.has_key(lext):
                        if line[0] != headerStartChar[lext]:
                            return BaseModel, ''
                        headerInfo = identifyHeader[lext](line)
                        if headerInfo[0] != BaseModel:
                            return headerInfo
                return BaseModel, ''
            finally:
                f.close()
    return BaseModel, ''


#-Registration of this modules classes---------------------------------------
modelControllerReg = {EditorModels.TextModel: TextController,
                      EditorModels.BitmapFileModel: BitmapFileController}

# Default filetype
DefaultController = TextController
DefaultModel = EditorModels.TextModel
defaultExt = EditorModels.TextModel.ext

# Model identifiers for application type files
appModelIdReg = []

# Dictionaries of functions keyed on file extension
headerStartChar = {}
identifyHeader = {}
identifySource = {}
# dictionary of filetypes recognised by the whole name
fullnameTypes = {}

# Classed from which the Designer can load resources
resourceClasses = []
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.