Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
git-svn-id: http://projects.conceptive.be/camelot/svn/trunk@2560 8325946a-aa55-0410-8760-f0bc8c33efaa
  • Loading branch information
erikj committed Jun 7, 2012
1 parent 96ad0ac commit 59d9d2f
Show file tree
Hide file tree
Showing 29 changed files with 340 additions and 735 deletions.
37 changes: 37 additions & 0 deletions camelot/admin/action/form_action.py
Expand Up @@ -30,6 +30,7 @@


from application_action import ( ApplicationActionGuiContext, from application_action import ( ApplicationActionGuiContext,
ApplicationActionModelContext ) ApplicationActionModelContext )
import list_action


class FormActionModelContext( ApplicationActionModelContext ): class FormActionModelContext( ApplicationActionModelContext ):
"""On top of the attributes of the """On top of the attributes of the
Expand Down Expand Up @@ -184,6 +185,42 @@ def model_run( self, model_context ):
yield action_steps.DeleteObject( obj ) yield action_steps.DeleteObject( obj )
admin.expunge( obj ) admin.expunge( obj )


class ToPreviousForm( list_action.ToPreviousRow ):
"""Move to the previous form"""

def gui_run( self, gui_context ):
gui_context.view.to_previous()

def get_state( self, model_context ):
return Action.get_state( self, model_context )

class ToFirstForm( list_action.ToFirstRow ):
"""Move to the form"""

def gui_run( self, gui_context ):
gui_context.view.to_first()

def get_state( self, model_context ):
return Action.get_state( self, model_context )

class ToNextForm( list_action.ToNextRow ):
"""Move to the next form"""

def gui_run( self, gui_context ):
gui_context.view.to_next()

def get_state( self, model_context ):
return Action.get_state( self, model_context )

class ToLastForm( list_action.ToLastRow ):
"""Move to the last form"""

def gui_run( self, gui_context ):
gui_context.view.to_last()

def get_state( self, model_context ):
return Action.get_state( self, model_context )

def structure_to_form_actions( structure ): def structure_to_form_actions( structure ):
"""Convert a list of python objects to a list of form actions. If the python """Convert a list of python objects to a list of form actions. If the python
object is a tuple, a CallMethod is constructed with this tuple as arguments. If object is a tuple, a CallMethod is constructed with this tuple as arguments. If
Expand Down
20 changes: 19 additions & 1 deletion camelot/admin/application_admin.py
Expand Up @@ -31,7 +31,7 @@
from PyQt4.QtCore import Qt from PyQt4.QtCore import Qt
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui


from camelot.admin.action import list_action, application_action from camelot.admin.action import application_action, form_action, list_action
from camelot.core.utils import ugettext_lazy as _ from camelot.core.utils import ugettext_lazy as _
from camelot.view import art from camelot.view import art
from camelot.view import database_selection from camelot.view import database_selection
Expand Down Expand Up @@ -135,6 +135,12 @@ class ApplicationAdmin(QtCore.QObject):
help_actions = [ application_action.ShowHelp(), ] help_actions = [ application_action.ShowHelp(), ]
export_actions = [ list_action.PrintPreview(), export_actions = [ list_action.PrintPreview(),
list_action.ExportSpreadsheet() ] list_action.ExportSpreadsheet() ]
form_toolbar_actions = [ form_action.CloseForm(),
form_action.ToFirstForm(),
form_action.ToPreviousForm(),
form_action.ToNextForm(),
form_action.ToLastForm(),
application_action.Refresh() ]


def __init__(self): def __init__(self):
"""Construct an ApplicationAdmin object and register it as the """Construct an ApplicationAdmin object and register it as the
Expand Down Expand Up @@ -302,6 +308,18 @@ def get_form_actions( self ):
""" """
return [] return []


def get_form_toolbar_actions( self, toolbar_area ):
"""
:param toolbar_area: an instance of :class:`Qt.ToolBarArea` indicating
where the toolbar actions will be positioned
:return: a list of :class:`camelot.admin.action.base.Action` objects
that should be displayed on the toolbar of a form view. return
None if no toolbar should be created.
"""
if toolbar_area == Qt.TopToolBarArea:
return self.form_toolbar_actions

def get_main_menu( self ): def get_main_menu( self ):
""" """
:return: a list of :class:`camelot.admin.menu.Menu` objects, or None if :return: a list of :class:`camelot.admin.menu.Menu` objects, or None if
Expand Down
8 changes: 7 additions & 1 deletion camelot/admin/entity_admin.py
Expand Up @@ -548,7 +548,13 @@ def flush(self, entity_instance):
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
session = Session.object_session( entity_instance ) session = Session.object_session( entity_instance )
if session: if session:
modifications = self.get_modifications( entity_instance ) modifications = {}
try:
modifications = self.get_modifications( entity_instance )
except Exception, e:
# todo : there seems to be a bug in sqlalchemy that causes the
# get history to fail in some cases
logger.error( 'could not get modifications from object', exc_info = e )
session.flush( [entity_instance] ) session.flush( [entity_instance] )
# #
# If needed, track the changes # If needed, track the changes
Expand Down
15 changes: 15 additions & 0 deletions camelot/admin/object_admin.py
Expand Up @@ -353,6 +353,21 @@ def get_form_actions( self, obj ):
app_admin = self.get_application_admin() app_admin = self.get_application_admin()
from camelot.admin.action.form_action import structure_to_form_actions from camelot.admin.action.form_action import structure_to_form_actions
return app_admin.get_form_actions() + structure_to_form_actions( self.form_actions ) return app_admin.get_form_actions() + structure_to_form_actions( self.form_actions )

@model_function
def get_form_toolbar_actions( self, toolbar_area ):
"""
By default this function will return the same as :meth:`camelot.admin.application_admin.ApplicationAdmin.get_form_toolbar_actions`
:param toolbar_area: an instance of :class:`Qt.ToolBarArea` indicating
where the toolbar actions will be positioned
:return: a list of :class:`camelot.admin.action.base.Action` objects
that should be displayed on the toolbar of a form view. return
None if no toolbar should be created.
"""
app_admin = self.get_application_admin()
return app_admin.get_form_toolbar_actions( toolbar_area )


def get_related_toolbar_actions( self, toolbar_area, direction ): def get_related_toolbar_actions( self, toolbar_area, direction ):
"""Specify the toolbar actions that should appear in a OneToMany editor. """Specify the toolbar actions that should appear in a OneToMany editor.
Expand Down
64 changes: 25 additions & 39 deletions camelot/bin/meta.py
Expand Up @@ -168,8 +168,31 @@ class MyApplicationViewsTest( EntityViewsTest ):


('main.py', ''' ('main.py', '''
import logging import logging
logging.basicConfig(level=logging.ERROR) from camelot.core.conf import settings, SimpleSettings
logger = logging.getLogger('main')
logging.basicConfig( level = logging.ERROR )
logger = logging.getLogger( 'main' )
# begin custom settings
class MySettings( SimpleSettings ):
# add an ENGINE or a CAMELOT_MEDIA_ROOT method here to connect
# to another database or change the location where files are stored
def setup_model( self ):
"""This function will be called at application startup, it is used to
setup the model"""
from camelot.core.sql import metadata
metadata.bind = self.ENGINE()
import camelot.model.authentication
import camelot.model.i18n
import camelot.model.memento
import {{options.module}}.model
metadata.create_all()
my_settings = MySettings( '{{options.author}}', '{{options.name}}' )
settings.append( my_settings )
# end custom settings
def start_application(): def start_application():
from camelot.view.main import main from camelot.view.main import main
Expand Down Expand Up @@ -221,45 +244,8 @@ def start_application():
include include
license license
libs libs
'''),
('settings.py', '''
import logging
import os
logger = logging.getLogger('settings')
# media root needs to be an absolute path for the file open functions
# to function correctly
CAMELOT_MEDIA_ROOT = os.path.join(os.path.dirname(__file__), 'media')
# backup root is the directory where the default backups are stored
CAMELOT_BACKUP_ROOT = os.path.join(os.path.dirname(__file__), 'backup')
# default extension for backup files
CAMELOT_BACKUP_EXTENSION = 'db'
# template used to create and find default backups
CAMELOT_BACKUP_FILENAME_TEMPLATE = 'default-backup-%(text)s.' + CAMELOT_BACKUP_EXTENSION
def ENGINE():
"""This function should return a database engine"""
from sqlalchemy import create_engine
return create_engine('sqlite:///model-data.sqlite')
def setup_model():
"""This function will be called at application startup, it is used to setup
the model"""
from camelot.core.sql import metadata
metadata.bind = ENGINE()
import camelot.model.authentication
import camelot.model.i18n
import camelot.model.memento
import {{options.module}}.model
metadata.create_all()
'''), '''),
('setup.py', ''' ('setup.py', '''
# #
# Default setup file for a Camelot application # Default setup file for a Camelot application
# #
Expand Down
6 changes: 4 additions & 2 deletions camelot/core/conf.py
Expand Up @@ -107,8 +107,10 @@ def __init__( self, author, name ):
:param author: the name of the writer of the application :param author: the name of the writer of the application
:param name: the name of the application :param name: the name of the application
these name will be used to create a folder where the local data will These names will be used to create a folder where the local data will
be stored. be stored. On Windows this will be in the AppData folder of the user,
otherwise it will be in a `.author` folder in the home directory of the
user.
""" """
if ('win' in sys.platform) and ('darwin' not in sys.platform): if ('win' in sys.platform) and ('darwin' not in sys.platform):
import winpaths import winpaths
Expand Down

0 comments on commit 59d9d2f

Please sign in to comment.