diff --git a/.gitignore b/.gitignore index 89fa1f451f..e092b6a477 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ site_media/photologue/photos/* site_media/photologue/photos/cache/* *.sqlite settings_local.py +site_media/documents/* diff --git a/apps/common/__init__.py b/apps/common/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/common/api.py b/apps/common/api.py new file mode 100644 index 0000000000..30b6579118 --- /dev/null +++ b/apps/common/api.py @@ -0,0 +1,32 @@ +import copy + +object_navigation = {} +menu_links = [] + +def register_links(src, links, menu_name=None): + if menu_name in object_navigation: + if hasattr(src, '__iter__'): + for one_src in src: + if one_src in object_navigation[menu_name]: + object_navigation[menu_name][one_src]['links'].extend(links) + else: + object_navigation[menu_name][one_src]={'links':copy.copy(links)} + else: + if src in object_navigation[menu_name]: + object_navigation[menu_name][src]['links'].extend(links) + else: + object_navigation[menu_name][src] = {'links':links} + else: + object_navigation[menu_name] = {} + if hasattr(src, '__iter__'): + for one_src in src: + object_navigation[menu_name][one_src] = {'links':links} + else: + object_navigation[menu_name] = {src:{'links':links}} + + +def register_menu(links): + for link in links: + menu_links.append(link) + + menu_links.sort(lambda x,y: 1 if x>y else -1, lambda x:x['position'] if 'position' in x else 1) diff --git a/apps/common/forms.py b/apps/common/forms.py new file mode 100644 index 0000000000..9cc13fca7f --- /dev/null +++ b/apps/common/forms.py @@ -0,0 +1,109 @@ +from django import forms +from django.utils.safestring import mark_safe +from django.utils.translation import ugettext as _ +from django.db import models +import types + + +def return_attrib(obj, attrib, arguments=None): + try: + result = reduce(getattr, attrib.split("."), obj) + if isinstance(result, types.MethodType): + if arguments: + return result(**arguments) + else: + return result() + else: + return result + except Exception, err: + if settings.DEBUG: + return "Attribute error: %s; %s" % (attrib, err) + else: + pass + + +class DetailSelectMultiple(forms.widgets.SelectMultiple): + def __init__(self, queryset=None, *args, **kwargs): + self.queryset=queryset + super(DetailSelectMultiple, self).__init__(*args, **kwargs) + + def render(self, name, value, attrs=None, choices=()): + if value is None: value = '' + #final_attrs = self.build_attrs(attrs, name=name) + output = u'\n') + + +class DetailForm(forms.ModelForm): + def __init__(self, extra_fields=None, *args, **kwargs): + super(DetailForm, self).__init__(*args, **kwargs) + if extra_fields: + for extra_field in extra_fields: + result = return_attrib(self.instance, extra_field['field']) + label = 'label' in extra_field and extra_field['label'] or None + #TODO: Add others result types <=> Field types + if isinstance(result, models.query.QuerySet): + self.fields[extra_field['field']]=forms.ModelMultipleChoiceField(queryset=result, label=label) + + for field_name, field in self.fields.items(): + if isinstance(field.widget, forms.widgets.SelectMultiple): + self.fields[field_name].widget = DetailSelectMultiple( + choices=field.widget.choices, + attrs=field.widget.attrs, + queryset=getattr(field, 'queryset', None), + ) + self.fields[field_name].help_text='' + elif isinstance(field.widget, forms.widgets.Select): + self.fields[field_name].widget = DetailSelectMultiple( + choices=field.widget.choices, + attrs=field.widget.attrs, + queryset=getattr(field, 'queryset', None), + ) + self.fields[field_name].help_text='' + + +class GenericConfirmForm(forms.Form): + pass + + +class GenericAssignRemoveForm(forms.Form): + left_list = forms.ModelMultipleChoiceField(required=False, queryset=None) + right_list = forms.ModelMultipleChoiceField(required=False, queryset=None) + def __init__(self, left_list_qryset=None, right_list_qryset=None, left_filter=None, *args, **kwargs): + super(GenericAssignRemoveForm, self).__init__(*args, **kwargs) + if left_filter: + self.fields['left_list'].queryset = left_list_qryset.filter(*left_filter) + else: + self.fields['left_list'].queryset = left_list_qryset + + self.fields['right_list'].queryset = right_list_qryset + + +class FilterForm(forms.Form): + def __init__(self, list_filters, *args, **kwargs): + super(FilterForm, self).__init__(*args, **kwargs) + for list_filter in list_filters: + label = list_filter.get('title', list_filter['name']) + self.fields[list_filter['name']] = forms.ModelChoiceField(queryset=list_filter['queryset'], label=label[0].upper() + label[1:], required=False) diff --git a/apps/common/locale/es/LC_MESSAGES/django.mo b/apps/common/locale/es/LC_MESSAGES/django.mo new file mode 100644 index 0000000000..8a5a40f2ec Binary files /dev/null and b/apps/common/locale/es/LC_MESSAGES/django.mo differ diff --git a/apps/common/locale/es/LC_MESSAGES/django.po b/apps/common/locale/es/LC_MESSAGES/django.po new file mode 100644 index 0000000000..3f5f47585b --- /dev/null +++ b/apps/common/locale/es/LC_MESSAGES/django.po @@ -0,0 +1,33 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-01-28 09:33-0400\n" +"PO-Revision-Date: 2011-01-28 09:33\n" +"Last-Translator: \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: \n" +"X-Translated-Using: django-rosetta 0.5.6\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: views.py:6 templates/password_change_done.html:5 +msgid "Your password has been successfully changed." +msgstr "Su contraseña se ha modificado correctamente." + +#: templates/login.html:5 +msgid "Login" +msgstr "Iniciar sesión" + +#: templates/password_change_done.html:3 templates/password_change_form.html:3 +#: templates/password_change_form.html:5 +msgid "Password change" +msgstr "Cambio de contraseña" diff --git a/apps/common/locale/ru/LC_MESSAGES/django.mo b/apps/common/locale/ru/LC_MESSAGES/django.mo new file mode 100644 index 0000000000..f5eb6fdf00 Binary files /dev/null and b/apps/common/locale/ru/LC_MESSAGES/django.mo differ diff --git a/apps/common/locale/ru/LC_MESSAGES/django.po b/apps/common/locale/ru/LC_MESSAGES/django.po new file mode 100644 index 0000000000..73789abb79 --- /dev/null +++ b/apps/common/locale/ru/LC_MESSAGES/django.po @@ -0,0 +1,33 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-01-30 16:51+0300\n" +"PO-Revision-Date: 2011-01-30 13:08\n" +"Last-Translator: \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: \n" +"X-Translated-Using: django-rosetta 0.5.5\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#: views.py:6 templates/password_change_done.html:5 +msgid "Your password has been successfully changed." +msgstr "Ваш пароль был успешно изменен." + +#: templates/login.html:5 +msgid "Login" +msgstr "Логин" + +#: templates/password_change_done.html:3 templates/password_change_form.html:3 +#: templates/password_change_form.html:5 +msgid "Password change" +msgstr "Сменить пароль" diff --git a/apps/common/models.py b/apps/common/models.py new file mode 100644 index 0000000000..71a8362390 --- /dev/null +++ b/apps/common/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/apps/common/templates/404.html b/apps/common/templates/404.html new file mode 100644 index 0000000000..a3e4254cab --- /dev/null +++ b/apps/common/templates/404.html @@ -0,0 +1,9 @@ +{% extends "base.html" %} + +{% block title %}Page not found{% endblock %} + +{% block content %} +

Page not found

+ +

Sorry, but the requested page could not be found.

+{% endblock %} diff --git a/apps/common/templates/500.html b/apps/common/templates/500.html new file mode 100644 index 0000000000..2deb3b32bc --- /dev/null +++ b/apps/common/templates/500.html @@ -0,0 +1,15 @@ + + + + Page unavailable + + +

Page unavailable

+ +

Sorry, but the requested page is unavailable due to a + server problem.

+ +

Administrators have been notified, so check back later.

+ + diff --git a/apps/common/templates/calculate_form_title.html b/apps/common/templates/calculate_form_title.html new file mode 100644 index 0000000000..2994f1d338 --- /dev/null +++ b/apps/common/templates/calculate_form_title.html @@ -0,0 +1,30 @@ +{% load i18n %} +{% if title %} + {% if striptags %} + {{ title|capfirst|striptags }} + {% else %} + {{ title|capfirst|safe }} + {% endif %} +{% else %} + {% if read_only %} + {% if object_name %} + {% blocktrans %}Details for {{ object_name }}: {{ object }}{% endblocktrans %} + {% else %} + {% blocktrans %}Details for: {{ object }}{% endblocktrans %} + {% endif %} + {% else %} + {% if object %} + {% if object_name %} + {% blocktrans %}Edit {{ object_name }}:{% endblocktrans %} {% if not striptags %}{% endif %}{{ object|capfirst }}{% if not striptags %}{% endif %} + {% else %} + {% trans "Edit" %}: {% if not striptags %}{% endif %}{{ object|capfirst }}{% if not striptags %}{% endif %} + {% endif %} + {% else %} + {% if object_name %} + {% blocktrans %}Create new {{ object_name }}{% endblocktrans %} + {% else %} + {% trans "Create" %} + {% endif %} + {% endif %} + {% endif %} +{% endif %} diff --git a/apps/common/templates/generic_assign_remove.html b/apps/common/templates/generic_assign_remove.html new file mode 100644 index 0000000000..6a75dfe917 --- /dev/null +++ b/apps/common/templates/generic_assign_remove.html @@ -0,0 +1,43 @@ +{% extends "base.html" %} +{% load i18n %} +{% block title %} :: {% blocktrans %}Assign {{ title }} {{ object }}{% endblocktrans %}{% endblock %} + + +{% block content %} + +
+

{{ title|safe }}

+ +
{% csrf_token %} + + + + + + + + + + + + {{ form.media|safe }} + +
{{ left_list_title }}{{ right_list_title }}
+ {{ form.left_list }}{{ form.left_list.errors }} + + + + + + + + + + +
+
{{ form.right_list }}{{ form.right_list.errors }}
+
+
+{% endblock %} diff --git a/apps/common/templates/generic_confirm.html b/apps/common/templates/generic_confirm.html new file mode 100755 index 0000000000..35f0bd6242 --- /dev/null +++ b/apps/common/templates/generic_confirm.html @@ -0,0 +1,51 @@ +{% extends 'base.html' %} +{% load i18n %} +{% block title %} :: {% trans 'Confirm' %} {{ title }}{% endblock %} + +{% block sidebar %} + {% for subtemplate in subtemplates %} + {% include subtemplate %} + {% endfor %} +{% endblock %} + +{% block content %} +
+
+ {% if delete_view %} +

{% trans 'Confirm delete' %}

+ {% else %} +

{% trans 'Confirm' %}

+ {% endif %} + +
+
+{% endblock %} diff --git a/apps/common/templates/generic_detail.html b/apps/common/templates/generic_detail.html new file mode 100755 index 0000000000..0f3e66761b --- /dev/null +++ b/apps/common/templates/generic_detail.html @@ -0,0 +1,64 @@ +{% extends "base.html" %} +{% load i18n %} +{% load styling %} +{% load generic_views_helpers %} +{% block title %} :: {% with "true" as read_only %}{% with "true" as striptags %}{% include "calculate_form_title.html" %}{% endwith %}{% endwith %}{% endblock %} + +{% block javascript %} + +{% endblock %} + +{% block sidebar %} + {% for subtemplate in sidebar_subtemplates %} + {% include subtemplate %} + {% endfor %} +{% endblock %} + +{% block stylesheets %} + +{% endblock %} + +{% block content %} +
+ {% with "true" as read_only %} + {% include "generic_form_subtemplate.html" %} + {% endwith %} +
+ + {% for subtemplate in subtemplates %} +
+ {% include subtemplate %} +
+ {% endfor %} + + {% for subtemplate in subtemplates_dict %} + {% with subtemplate.title as title %} + {% with subtemplate.object_list as object_list %} + {% with subtemplate.extra_columns as extra_columns %} + {% with subtemplate.hide_object as hide_object %} + {% with subtemplate.main_object as main_object %} +
+ {% include subtemplate.name %} +
+ {% endwith %} + {% endwith %} + {% endwith %} + {% endwith %} + {% endwith %} + {% endfor %} + + +{% endblock %} + diff --git a/apps/common/templates/generic_form.html b/apps/common/templates/generic_form.html new file mode 100755 index 0000000000..755174435b --- /dev/null +++ b/apps/common/templates/generic_form.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} +{% block title %} :: {% with "true" as striptags %}{% include "calculate_form_title.html" %}{% endwith %}{% endblock %} + +{% block content %} + {% include "generic_form_subtemplate.html" %} +{% endblock %} diff --git a/apps/common/templates/generic_form_instance.html b/apps/common/templates/generic_form_instance.html new file mode 100644 index 0000000000..d291d382f9 --- /dev/null +++ b/apps/common/templates/generic_form_instance.html @@ -0,0 +1,39 @@ +{% load i18n %} +{% load styling %} +{{ form.media|safe }} +{% add_classes_to_form form %} + +{% if form.non_field_errors %} +
+ {% for value in form.non_field_errors %} +
+

{{ value }}

+
+ {% endfor %} +
+{% endif %} + +{% if form_display_mode_table %} + {% for field in form.hidden_fields %} + {{ field }} + {% endfor %} + + {% for field in form.visible_fields %} + + {% if field.errors %}
{% endif %} + {{ field }} + {% if field.errors %}
{% endif %} + + {% endfor %} + +{% else %} + {% for field in form %} +
+ {% if field.errors %}
{% endif %} + + {% if field.errors %}{% for error in field.errors %}{{ error }}{% if not forloop.last %} | {% endif %}{% endfor %}
{% endif %} + {{ field }} + {% if field.help_text %}{{ field.help_text }}{% endif %} +
+ {% endfor %} +{% endif %} diff --git a/apps/common/templates/generic_form_subtemplate.html b/apps/common/templates/generic_form_subtemplate.html new file mode 100755 index 0000000000..81c43574e2 --- /dev/null +++ b/apps/common/templates/generic_form_subtemplate.html @@ -0,0 +1,87 @@ +{% load i18n %} + +{% if side_bar %} +
+

+{% else %} +
+

+{% endif %} + +{% include "calculate_form_title.html" %} + +{% if side_bar %} +

+
+

+{% else %} +

+
+{% endif %} + + {% if form.is_multipart %} +
+ {% else %} + + {% endif %} + {% if step_field %} + + {% endif %} + + {% if submit_method != 'GET' and submit_method != 'get' %} + {% csrf_token %} + {% endif %} + + {% for hidden_field in hidden_fields %} + {{ hidden_field.as_hidden }} + {% endfor %} + + {% if form.management_form %} + {% with form as formset %} + {{ formset.management_form }} + + {% if form_display_mode_table %} + + + + {% for field in formset.forms.0.visible_fields %} + + {#{% if field.help_text %}{{ field.help_text }}{% endif %}#} + {% endfor %} + + {% endif %} + + {% for form in formset.forms %} + {% include "generic_form_instance.html" %} + {% endfor %} + {% if form_display_mode_table %} + +
+ {{ field.label_tag }}{% if field.field.required and not read_only %} ({% trans 'required' %}){% endif %} +
+ {% endif %} + {% endwith %} + {% else %} + {% include "generic_form_instance.html" %} + {% endif %} + + {% if not read_only %} + + {% endif %} +
+ {% if sidebar %} +

+ {% else %} + + {% endif %} + + diff --git a/apps/common/templates/generic_list.html b/apps/common/templates/generic_list.html new file mode 100755 index 0000000000..b6acb740ae --- /dev/null +++ b/apps/common/templates/generic_list.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} +{% load i18n %} +{% block title %} :: {% blocktrans %}List of {{ title }}{% endblocktrans %}{% endblock %} +{#{% block secondary_links %}{{ secondary_links|safe }}{% endblock %}#} + +{% block content %} + {% include 'generic_list_subtemplate.html' %} +{% endblock %} diff --git a/apps/common/templates/generic_list_subtemplate.html b/apps/common/templates/generic_list_subtemplate.html new file mode 100644 index 0000000000..340765d59c --- /dev/null +++ b/apps/common/templates/generic_list_subtemplate.html @@ -0,0 +1,71 @@ +{% load i18n %} +{% load attribute_tags %} +{% load pagination_tags %} +{% load navigation %} + +{% if side_bar %} +
+

+ {{ title }} +

+
+

+{% else %} + {% autopaginate object_list %} +

+

+ {% ifnotequal page_obj.paginator.num_pages 1 %} + {% blocktrans with page_obj.start_index as start and page_obj.end_index as end and page_obj.paginator.object_list|length as total %}List of {{ title }} ({{ start }} - {{ end }} out of {{ total }}){% endblocktrans %} + {% else %} + {% blocktrans with page_obj.paginator.object_list|length as total %}List of {{ title }} ({{ total }}){% endblocktrans %} + {% endifnotequal %} +

+ +
+{% endif %} + +
+ + + {% if not hide_header %} + + {% if not hide_object %} + + {% endif %} + {% for column in extra_columns %} + + {% endfor %} + {% if not hide_links %} + + {% endif %} + + {% endif %} + {% for object in object_list %} + + {% if not hide_object %} + {% if main_object %} + {% with object|object_property:main_object as object %} + + {% endwith %} + {% else %} + + {% endif %} + {% endif %} + {% for column in extra_columns %} + + {% endfor %} + {% if not hide_links %} + + {% endif %} + + {% empty %} + + {% endfor %} + +
{% trans 'Identifier' %}{{ column.name|capfirst }} 
{% if not hide_link %}{{ object }}{% else %}{{ object }}{% endif %}{% if not hide_link %}{{ object }}{% else %}{{ object }}{% endif %}{{ object|object_property:column.attribute|safe }} + {% object_navigation_template %} +
{% blocktrans %}There are no {{ title }}{% endblocktrans %}
+ {% paginate %} +
+
+
diff --git a/apps/common/templates/generic_navigation.html b/apps/common/templates/generic_navigation.html new file mode 100755 index 0000000000..6829cde23c --- /dev/null +++ b/apps/common/templates/generic_navigation.html @@ -0,0 +1,7 @@ +{% load i18n %} + +{% for link in object_navigation_links %} + {% if as_li %}
  • {% endif %} + {% if link.famfam %}{% endif %}{{ link.text|capfirst }}{% if link.error %} - {{ link.error }}{% endif %}{% if link.active %}{% endif %}{% if horizontal %}{% if not forloop.last %} | {% endif %}{% endif %} + {% if as_li %}
  • {% endif %} +{% endfor %} diff --git a/apps/common/templates/generic_wizard.html b/apps/common/templates/generic_wizard.html new file mode 100644 index 0000000000..dd4ad78d59 --- /dev/null +++ b/apps/common/templates/generic_wizard.html @@ -0,0 +1,17 @@ +{% extends "base.html" %} +{% load i18n %} +{% load styling %} +{% add_classes_to_form form %} +{% block content %} + {% with step_title as title %} + {% with previous_fields as hidden_fields %} + {% if form.management_form %} + {% with "true" as form_display_mode_table %} + {% include "generic_form_subtemplate.html" %} + {% endwith %} + {% else %} + {% include "generic_form_subtemplate.html" %} + {% endif %} + {% endwith %} + {% endwith %} +{% endblock %} diff --git a/apps/common/templates/login.html b/apps/common/templates/login.html new file mode 100755 index 0000000000..60e82f69a3 --- /dev/null +++ b/apps/common/templates/login.html @@ -0,0 +1,6 @@ +{% extends "web_theme_login.html" %} +{% load i18n %} +{% load project_tags %} + +{% block html_title %}{% project_name %} :: {% trans "Login" %}{% endblock %} +{% block project_name %}{% project_name %}{% endblock %} diff --git a/apps/common/templates/password_change_done.html b/apps/common/templates/password_change_done.html new file mode 100755 index 0000000000..297480cb10 --- /dev/null +++ b/apps/common/templates/password_change_done.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} +{% load i18n %} +{% block title %} :: {% trans "Password change" %}{% endblock %} +{% block content %} +

    {% trans "Your password has been successfully changed." %}

    +{% endblock %} diff --git a/apps/common/templates/password_change_form.html b/apps/common/templates/password_change_form.html new file mode 100755 index 0000000000..701a6ecace --- /dev/null +++ b/apps/common/templates/password_change_form.html @@ -0,0 +1,11 @@ +{% extends "generic_form.html" %} +{% load i18n %} +{% block title %} :: {% trans "Password change" %}{% endblock %} + +{% block form_title %}{% trans "Password change" %}{% endblock %} + + + + + + diff --git a/apps/common/templatetags/__init__.py b/apps/common/templatetags/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/common/templatetags/attribute_tags.py b/apps/common/templatetags/attribute_tags.py new file mode 100644 index 0000000000..949ae2eaf4 --- /dev/null +++ b/apps/common/templatetags/attribute_tags.py @@ -0,0 +1,34 @@ +import types + +from django.core.urlresolvers import reverse +from django.conf import settings +from django.template.defaultfilters import stringfilter +from django.template import Library, Node, Variable, VariableDoesNotExist + + +register = Library() + +def return_attrib(obj, attrib, arguments={}): + try: + if isinstance(obj, types.DictType) or isinstance(obj, types.DictionaryType): + return obj[attrib] + elif isinstance(attrib, types.FunctionType): + return attrib(obj) + else: + result = reduce(getattr, attrib.split("."), obj) + if isinstance(result, types.MethodType): + if arguments: + return result(**arguments) + else: + return result() + else: + return result + except Exception, err: + if settings.DEBUG: + return "Error: %s; %s" % (attrib, err) + else: + pass + +@register.filter +def object_property(value, arg): + return return_attrib(value, arg) diff --git a/apps/common/templatetags/navigation.py b/apps/common/templatetags/navigation.py new file mode 100644 index 0000000000..980941596e --- /dev/null +++ b/apps/common/templatetags/navigation.py @@ -0,0 +1,228 @@ +import types + +from django.conf import settings +from django.core.urlresolvers import reverse, NoReverseMatch +from django.core.urlresolvers import RegexURLResolver, RegexURLPattern, Resolver404, get_resolver +from django.template import TemplateSyntaxError, Library, \ + VariableDoesNotExist, Node, Variable +from django.utils.text import unescape_string_literal + +from common.api import object_navigation, menu_links as menu_navigation + +register = Library() + + +def process_links(links, view_name, url): + items = [] + active_item = None + for item, count in zip(links, range(len(links))): + item_view = 'view' in item and item['view'] + item_url = 'url' in item and item['url'] + if view_name == item_view or url == item_url: + active = True + active_item = item + else: + active = False + if 'links' in item: + for child_link in item['links']: + child_view = 'view' in child_link and child_link['view'] + child_url = 'url' in child_link and child_link['url'] + if view_name == child_view or url == child_url: + active = True + active_item = item + + items.append( + { + 'first':count==0, + 'active':active, + 'url':item_view and reverse(item_view) or item_url or '#', + 'text':unicode(item['text']), + 'famfam':'famfam' in item and item['famfam'], + } + ) + return items, active_item + + +class NavigationNode(Node): + def __init__(self, navigation, *args, **kwargs): + self.navigation = navigation + + def render(self, context): + request = Variable('request').resolve(context) + view_name = resolve_to_name(request.META['PATH_INFO']) + + main_items, active_item = process_links(links=self.navigation, view_name=view_name, url=request.META['PATH_INFO']) + context['navigation_main_links'] = main_items + if active_item and 'links' in active_item: + secondary_links, active_item = process_links(links=active_item['links'], view_name=view_name, url=request.META['PATH_INFO']) + context['navigation_secondary_links'] = secondary_links + return '' + + +@register.tag +def main_navigation(parser, token): + args = token.split_contents() + +# if len(args) != 3 or args[1] != 'as': +# raise TemplateSyntaxError("'get_all_states' requires 'as variable' (got %r)" % args) + + #return NavigationNode(variable=args[2], navigation=navigation) + return NavigationNode(navigation=menu_navigation) + + +#http://www.djangosnippets.org/snippets/1378/ +__all__ = ('resolve_to_name',) + +def _pattern_resolve_to_name(self, path): + match = self.regex.search(path) + if match: + name = "" + if self.name: + name = self.name + elif hasattr(self, '_callback_str'): + name = self._callback_str + else: + name = "%s.%s" % (self.callback.__module__, self.callback.func_name) + return name + +def _resolver_resolve_to_name(self, path): + tried = [] + match = self.regex.search(path) + if match: + new_path = path[match.end():] + for pattern in self.url_patterns: + try: + name = pattern.resolve_to_name(new_path) + except Resolver404, e: + tried.extend([(pattern.regex.pattern + ' ' + t) for t in e.args[0]['tried']]) + else: + if name: + return name + tried.append(pattern.regex.pattern) + raise Resolver404, {'tried': tried, 'path': new_path} + + +# here goes monkeypatching +RegexURLPattern.resolve_to_name = _pattern_resolve_to_name +RegexURLResolver.resolve_to_name = _resolver_resolve_to_name + +def resolve_to_name(path, urlconf=None): + return get_resolver(urlconf).resolve_to_name(path) + +@register.filter +def resolve_url_name(value): + return resolve_to_name(value) + +def resolve_arguments(context, src_args): + args = [] + kwargs = {} + if type(src_args) == type([]): + for i in src_args: + val = resolve_template_variable(context, i) + if val: + args.append(val) + elif type(src_args) == type({}): + for key, value in src_args.items(): + val = resolve_template_variable(context, value) + if val: + kwargs[key] = val + else: + val = resolve_template_variable(context, src_args) + if val: + args.append(val) + + return args, kwargs + + +def resolve_links(context, links, current_view, current_path): + context_links = [] + for link in links: + args, kwargs = resolve_arguments(context, link.get('args', {})) + + if 'view' in link: + link['active'] = link['view'] == current_view + args, kwargs = resolve_arguments(context, link.get('args', {})) + + try: + if kwargs: + link['url'] = reverse(link['view'], kwargs=kwargs) + else: + link['url'] = reverse(link['view'], args=args) + except NoReverseMatch, err: + link['url'] = '#' + link['error'] = err + elif 'url' in link: + link['active'] = link['url'] == current_path + else: + link['active'] = False + context_links.append(link) + + return context_links + +def _get_object_navigation_links(context, menu_name=None): + current_path = Variable('request').resolve(context).META['PATH_INFO'] + current_view = resolve_to_name(current_path)#.get_full_path()) + context_links = [] + + try: + object_name = Variable('navigation_object_name').resolve(context) + except VariableDoesNotExist: + object_name = 'object' + + try: + obj = Variable(object_name).resolve(context) + except VariableDoesNotExist: + obj = None + + try: + links = object_navigation[menu_name][current_view]['links'] + for link in resolve_links(context, links, current_view, current_path): + context_links.append(link) + except KeyError: + pass + + try: + links = object_navigation[menu_name][type(obj)]['links'] + for link in resolve_links(context, links, current_view, current_path): + context_links.append(link) + except KeyError: + pass + + return context_links + + +def resolve_template_variable(context, name): + try: + return unescape_string_literal(name) + except ValueError: + return Variable(name).resolve(context) + except TypeError: + return name + + +class GetNavigationLinks(Node): + def __init__(self, *args): + self.menu_name = None + if args: + self.menu_name = args[0] + + def render(self, context): + menu_name = resolve_template_variable(context, self.menu_name) + context['object_navigation_links'] = _get_object_navigation_links(context, menu_name) + return '' + + +@register.tag +def get_object_navigation_links(parser, token): + args = token.split_contents() + return GetNavigationLinks(*args[1:]) + + +def object_navigation_template(context): + return { + 'horizontal':True, + 'object_navigation_links':_get_object_navigation_links(context) + } + return new_context +register.inclusion_tag('generic_navigation.html', takes_context=True)(object_navigation_template) + diff --git a/apps/common/templatetags/project_tags.py b/apps/common/templatetags/project_tags.py new file mode 100644 index 0000000000..cfa1e7acfa --- /dev/null +++ b/apps/common/templatetags/project_tags.py @@ -0,0 +1,8 @@ +from django.template import TemplateSyntaxError, Library, VariableDoesNotExist +from django.conf import settings + +register = Library() + +@register.simple_tag +def project_name(): + return settings.PROJECT_TITLE diff --git a/apps/common/tests.py b/apps/common/tests.py new file mode 100644 index 0000000000..2247054b35 --- /dev/null +++ b/apps/common/tests.py @@ -0,0 +1,23 @@ +""" +This file demonstrates two different styles of tests (one doctest and one +unittest). These will both pass when you run "manage.py test". + +Replace these with more appropriate tests for your application. +""" + +from django.test import TestCase + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.failUnlessEqual(1 + 1, 2) + +__test__ = {"doctest": """ +Another way to test that 1 + 1 is equal to 2. + +>>> 1 + 1 == 2 +True +"""} + diff --git a/apps/common/urls.py b/apps/common/urls.py new file mode 100644 index 0000000000..fdd7fa8b40 --- /dev/null +++ b/apps/common/urls.py @@ -0,0 +1,25 @@ +from django.conf.urls.defaults import * +from django.views.generic.simple import direct_to_template + + +urlpatterns = patterns('common.views', + url(r'^about/$', direct_to_template, { 'template' : 'about.html'}, 'about'), + url(r'^password/change/done/$', 'password_change_done', (), name='password_change_done'), +) + +urlpatterns += patterns('', + url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}, name='login_view'), + url(r'^logout/$', 'django.contrib.auth.views.logout', {'next_page' : '/'}, name='logout_view' ), + + url(r'^password/change/$', 'django.contrib.auth.views.password_change', {'template_name': 'password_change_form.html', 'post_change_redirect': '/password/change/done/'}, name='password_change_view'), + #url(r'^password/change/done/$', 'django.contrib.auth.views.password_change_done', {'template_name': 'password_change_done.html'}), + + url(r'^password/reset/$', 'django.contrib.auth.views.password_reset', {'email_template_name' : 'password_reset_email.html', 'template_name': 'password_reset_form.html', 'post_reset_redirect' : '/password/reset/done'}, name='password_reset_view'), + url(r'^password/reset/confirm/(?P[0-9A-Za-z]+)-(?P.+)/$', 'django.contrib.auth.views.password_reset_confirm', { 'template_name' : 'password_reset_confirm.html', 'post_reset_redirect' : '/password/reset/complete/'}, name='password_reset_confirm_view'), + url(r'^password/reset/complete/$', 'django.contrib.auth.views.password_reset_complete', { 'template_name' : 'password_reset_complete.html' }, name='password_reset_complete_view'), + url(r'^password/reset/done/$', 'django.contrib.auth.views.password_reset_done', { 'template_name' : 'password_reset_done.html'}, name='password_reset_done_view'), +) + +urlpatterns += patterns('', + url(r'^set_language/$', 'django.views.i18n.set_language', name='set_language'), +) diff --git a/apps/common/utils.py b/apps/common/utils.py new file mode 100644 index 0000000000..2ba7e0b7ca --- /dev/null +++ b/apps/common/utils.py @@ -0,0 +1,40 @@ +from django.utils.http import urlquote as django_urlquote +from django.utils.http import urlencode as django_urlencode +from django.utils.datastructures import MultiValueDict + +def urlquote(link=None, get={}): + u''' + This method does both: urlquote() and urlencode() + + urlqoute(): Quote special characters in 'link' + + urlencode(): Map dictionary to query string key=value&... + + HTML escaping is not done. + + Example: + + urlquote('/wiki/Python_(programming_language)') --> '/wiki/Python_%28programming_language%29' + urlquote('/mypath/', {'key': 'value'}) --> '/mypath/?key=value' + urlquote('/mypath/', {'key': ['value1', 'value2']}) --> '/mypath/?key=value1&key=value2' + urlquote({'key': ['value1', 'value2']}) --> 'key=value1&key=value2' + ''' + assert link or get + if isinstance(link, dict): + # urlqoute({'key': 'value', 'key2': 'value2'}) --> key=value&key2=value2 + assert not get, get + get=link + link='' + assert isinstance(get, dict), 'wrong type "%s", dict required' % type(get) + #assert not (link.startswith('http://') or link.startswith('https://')), \ + # 'This method should only quote the url path. It should not start with http(s):// (%s)' % ( + # link) + if get: + # http://code.djangoproject.com/ticket/9089 + if isinstance(get, MultiValueDict): + get=get.lists() + if link: + link='%s?' % django_urlquote(link) + return u'%s%s' % (link, django_urlencode(get, doseq=True)) + else: + return django_urlquote(link) diff --git a/apps/common/views.py b/apps/common/views.py new file mode 100644 index 0000000000..f435cbc6d3 --- /dev/null +++ b/apps/common/views.py @@ -0,0 +1,7 @@ +from django.shortcuts import redirect +from django.utils.translation import ugettext as _ +from django.contrib import messages + +def password_change_done(request): + messages.success(request, _(u'Your password has been successfully changed.')) + return redirect('home') diff --git a/apps/common/wizard.py b/apps/common/wizard.py new file mode 100644 index 0000000000..c7622fbd92 --- /dev/null +++ b/apps/common/wizard.py @@ -0,0 +1,82 @@ +"""Common abstract classes for forms.""" +try: + import cPickle as pickle +except ImportError: + import pickle + +from django import forms +from django.conf import settings +from django.contrib.formtools.wizard import FormWizard +from django.forms.forms import BoundField +from django.forms.formsets import BaseFormSet +from django.utils.hashcompat import md5_constructor + +__all__ = ('security_hash', 'BoundFormWizard') + +def security_hash(request, form, exclude=None, *args): + """Calculates a security hash for the given Form/FormSet instance. + + This creates a list of the form field names/values in a deterministic + order, pickles the result with the SECRET_KEY setting, then takes an md5 + hash of that. + """ + + data = [] + if exclude is None: + exclude = () + if isinstance(form, BaseFormSet): + for _form in form.forms + [form.management_form]: + for bf in _form: + value = bf.field.clean(bf.data) or '' + if isinstance(value, basestring): + value = value.strip() + data.append((bf.name, value)) + else: + for bf in form: + if bf.name in exclude: + continue + value = bf.field.clean(bf.data) or '' + if isinstance(value, basestring): + value = value.strip() + data.append((bf.name, value)) + data.extend(args) + data.append(settings.SECRET_KEY) + + # Use HIGHEST_PROTOCOL because it's the most efficient. It requires + # Python 2.3, but Django requires 2.3 anyway, so that's OK. + pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) + + return md5_constructor(pickled).hexdigest() + +class BoundFormWizard(FormWizard): + """Render prev_fields as a list of bound form fields in the template + context rather than raw html.""" + def security_hash(self, request, form): + """Calculates the security hash for the given HttpRequest and + Form/FormSet instances. + + Subclasses may want to take into account request-specific information, + such as the IP address. + """ + return security_hash(request, form) + + def render(self, form, request, step, context=None): + "Renders the given Form object, returning an HttpResponse." + old_data = request.POST + prev_fields = [] + if old_data: + for i in range(step): + old_form = self.get_form(i, old_data) + hash_name = 'hash_%s' % i + if isinstance(old_form, BaseFormSet): + for _form in old_form.forms + [old_form.management_form]: + prev_fields.extend([bf for bf in _form]) + else: + prev_fields.extend([bf for bf in old_form]) + hash_field = forms.Field(initial=old_data.get(hash_name, + self.security_hash(request, old_form))) + bf = BoundField(forms.Form(), hash_field, hash_name) + prev_fields.append(bf) + return self.render_template(request, form, prev_fields, step, context) + +# vim: ai ts=4 sts=4 et sw=4 diff --git a/apps/documents/__init__.py b/apps/documents/__init__.py index e69de29bb2..427e2675a5 100644 --- a/apps/documents/__init__.py +++ b/apps/documents/__init__.py @@ -0,0 +1,12 @@ +from django.utils.translation import ugettext_lazy as _ + +from common.api import register_links, register_menu + +document_list = {'text':_(u'documents'), 'view':'document_list', 'famfam':'page'} +document_create = {'text':_('create document'), 'view':'document_create', 'famfam':'page_add'} + +register_menu([ + {'text':_('documents'), 'view':'document_list', 'links':[ + document_list, document_create + ],'famfam':'page','position':4}]) + diff --git a/apps/documents/admin.py b/apps/documents/admin.py index daeaf29f7e..4200b21b15 100644 --- a/apps/documents/admin.py +++ b/apps/documents/admin.py @@ -1,10 +1,11 @@ from django.contrib import admin from models import MetadataType, DocumentType, Document, \ - DocumentTypeMetadataTypeConnector + DocumentTypeMetadataType, DocumentMetadata admin.site.register(MetadataType) admin.site.register(DocumentType) admin.site.register(Document) -admin.site.register(DocumentTypeMetadataTypeConnector) +admin.site.register(DocumentTypeMetadataType) +admin.site.register(DocumentMetadata) diff --git a/apps/documents/forms.py b/apps/documents/forms.py new file mode 100644 index 0000000000..ea69118c95 --- /dev/null +++ b/apps/documents/forms.py @@ -0,0 +1,68 @@ +from django import forms +from django.utils.translation import ugettext_lazy as _ +from django.http import HttpResponseRedirect +from django.utils.http import urlencode +from django.core.urlresolvers import reverse + +from common.wizard import BoundFormWizard +from common.utils import urlquote + +from models import Document, DocumentType, DocumentTypeMetadataType + + +class DocumentForm(forms.ModelForm): + class Meta: + model = Document + + +class DocumentTypeSelectForm(forms.Form): + document_type = forms.ModelChoiceField(queryset=DocumentType.objects.all()) + + +class MetadataForm(forms.Form): + def __init__(self, *args, **kwargs): + if 'initial' in kwargs: + self.metadata_type = kwargs['initial'].pop('metadata_type', None) + super(MetadataForm, self).__init__(*args, **kwargs) + self.fields['id'] = forms.CharField(label=_(u'id'), widget=forms.HiddenInput) + self.fields['name'] = forms.CharField(label=_(u'Name'), + required=False, widget=forms.TextInput(attrs={'readonly':'readonly'})) + self.fields['value'] = forms.CharField(label=_(u'Value')) + if hasattr(self, 'metadata_type'): + self.fields['name'].initial=self.metadata_type.name + self.fields['id'].initial=self.metadata_type.id + + +class DocumentCreateWizard(BoundFormWizard): + def render_template(self, request, form, previous_fields, step, context=None): + context = {'step_title':self.extra_context['step_titles'][step]} + return super(DocumentCreateWizard, self).render_template(request, form, previous_fields, step, context) + + def parse_params(self, request, *args, **kwargs): + self.extra_context={'step_titles':[ + _(u'step 1 of 2: Document type'), + _(u'step 2 of 2: Document metadata'), + ]} + + def process_step(self, request, form, step): + if step == 0: + self.document_type = form.cleaned_data['document_type'] + + initial=[] + for item in DocumentTypeMetadataType.objects.filter(document_type=self.document_type): + initial.append({ + 'metadata_type':item.metadata_type, + }) + self.initial = {1:initial} + if step == 1: + self.urldata = [] + for metadata in form.cleaned_data: + self.urldata.append((metadata['id'],metadata['value'])) + + + def get_template(self, step): + return 'generic_wizard.html' + + def done(self, request, form_list): + url = reverse('upload_document_with_type', args=[self.document_type.id]) + return HttpResponseRedirect('%s?%s' % (url, urlencode(self.urldata))) diff --git a/apps/documents/models.py b/apps/documents/models.py index 6422bdd600..f146d9cfa1 100644 --- a/apps/documents/models.py +++ b/apps/documents/models.py @@ -1,5 +1,6 @@ import os import uuid +import mimetypes from datetime import datetime from django.db import models @@ -13,9 +14,8 @@ def get_filename_from_uuid(instance, filename, directory='documents'): def populate_file_extension_and_mimetype(instance, filename): # First populate the file extension and mimetype - instance.file_mimetype, encoding = guess_type(filename) or "" - slug, instance.file_extension = os.path.splitext(filename) - #instance.slug, instance.extension = os.path.splitext(filename) + instance.file_mimetype, encoding = mimetypes.guess_type(filename) or "" + instance.file_filename, instance.file_extension = os.path.splitext(filename) class DocumentType(models.Model): name = models.CharField(max_length=32, verbose_name=_(u'name')) @@ -30,66 +30,28 @@ class Document(models.Model): """ document_type = models.ForeignKey(DocumentType, verbose_name=_(u'document type')) file = models.FileField(upload_to=get_filename_from_uuid)#lambda i,f: 'documents/%s' % i.uuid) - uuid = models.CharField(max_length=36, default=lambda:unicode(uuid.uuid4()), blank=True, editable=False) - #file = models.FileField(upload_to=get_filename_from_uuid)#lambda i,f: 'documents/%s' % i.uuid) - #file_mimetype = models.CharField(max_length=50, default="", editable=False) - #file_extension = models.CharField(max_length=10, default="", editable=False) - + file_mimetype = models.CharField(max_length=50, default="", editable=False) + file_filename = models.CharField(max_length=64, default="", editable=False) + file_extension = models.CharField(max_length=10, default="", editable=False) date_added = models.DateTimeField("added", auto_now_add=True) date_updated = models.DateTimeField("updated", auto_now=True) - - #def save_file(self, contents, save=False): - # " Save a file, creating a new document_version if necessary. " - # self.file.save(contents.name, contents, save=save) - # # This is now done elsewhere - # #self.file_mimetype = guess_type(contents.name) or "" - # #try: - # #self.file_extension = contents[contents.rindex(".")+1:] or "" - # #except ValueError: - # #pass - # #self.save() - class Meta: verbose_name = _(u'document') - verbose_name_plural = _(u"documents") + verbose_name_plural = _(u'documents') def __unicode__(self): return self.uuid #@property #def friendly_filename(self): - # """ A friendly filename (ie not the UUID) for the user to see when they download. + # ''' A friendly filename (ie not the UUID) for the user to see when they download. # Overload this with eg a slug field. - # """ + # ''' # return 'untitled.%s' % self.file_extension - #def already(self, mode, request): - # """ Tests if a user has already viewed, downloaded or sent this document. - # Assumes this model has a log of document interactions. - # """ - # mode = getattr(DocumentInteractionBase.MODES, mode.upper()) - # - # if request.user.is_anonymous(): - # return bool(self.interactions.filter(mode=mode, session_key=request.session.session_key)) - # else: - # return bool(self.interactions.filter(mode=mode, user=request.user)) - - #@property - #def file_thumbnail_small(self): - # # TODO: subclass DjangoThumbnail to remove UUID from URL - # if DjangoThumbnail: - # return DjangoThumbnail(self.file.name, (200,200)) - - #@property - #def file_thumbnail_medium(self): - # # TODO: subclass DjangoThumbnail to remove UUID from URL - # if DjangoThumbnail: - # return DjangoThumbnail(self.file.name, (600,600)) - - class MetadataType(models.Model): name = models.CharField(max_length=32, verbose_name=_(u'name')) default = models.CharField(max_length=64, blank=True, null=True, verbose_name=_(u'default')) @@ -101,22 +63,36 @@ class MetadataType(models.Model): class Meta: verbose_name = _(u'metadata type') - verbose_name_plural = _(u"metadata types") + verbose_name_plural = _(u'metadata types') # @models.permalink # def get_absolute_url(self): # return ('state_list', []) -class DocumentTypeMetadataTypeConnector(models.Model): +class DocumentTypeMetadataType(models.Model): document_type = models.ForeignKey(DocumentType, verbose_name=_(u'document type')) metadata_type = models.ForeignKey(MetadataType, verbose_name=_(u'metadata type')) #override default - #create index dir + #create index dir? -bool + #required? -bool def __unicode__(self): return '%s <-> %s' %(self.document_type, self.metadata_type) class Meta: - verbose_name = _(u"document type metadata type connector") - verbose_name_plural = _(u"document type metadata type connectors") + verbose_name = _(u'document type metadata type connector') + verbose_name_plural = _(u'document type metadata type connectors') + + +class DocumentMetadata(models.Model): + document = models.ForeignKey(Document, verbose_name=_(u'document')) + metadata_type = models.ForeignKey(MetadataType, verbose_name=_(u'metadata type')) + value = models.TextField(blank=True, null=True, verbose_name=_(u'metadata value')) + + def __unicode__(self): + return '%s <-> %s' %(self.document, self.metadata_type) + + class Meta: + verbose_name = _(u'document metadata') + verbose_name_plural = _(u'document metadata') diff --git a/apps/documents/urls.py b/apps/documents/urls.py new file mode 100644 index 0000000000..8ab07bc62d --- /dev/null +++ b/apps/documents/urls.py @@ -0,0 +1,11 @@ +from django.conf.urls.defaults import * +from django.utils.translation import ugettext_lazy as _ +from django.views.generic.create_update import create_object, update_object + + +urlpatterns = patterns('documents.views', + url(r'^document/list/$', 'document_list', (), 'document_list'), + url(r'^document/create/$', 'document_create', (), 'document_create'), + #url(r'^document/upload/$', 'upload_document', (), 'upload_document'), + url(r'^document/type/(?P\d+)/upload/$', 'upload_document_with_type', (), 'upload_document_with_type'), +) diff --git a/apps/documents/views.py b/apps/documents/views.py index 60f00ef0ef..7814a24570 100644 --- a/apps/documents/views.py +++ b/apps/documents/views.py @@ -1 +1,65 @@ -# Create your views here. +import datetime + +from django.utils.translation import ugettext as _ +from django.http import HttpResponse, HttpResponseRedirect +from django.shortcuts import render_to_response, get_object_or_404, redirect +from django.template import RequestContext +from django.contrib import messages +from django.views.generic.list_detail import object_detail, object_list +from django.core.urlresolvers import reverse +from django.views.generic.create_update import create_object +from django.forms.formsets import formset_factory + + +from models import Document, DocumentMetadata, DocumentType, MetadataType +from forms import DocumentTypeSelectForm, DocumentCreateWizard, \ + MetadataForm, DocumentForm + + +def document_list(request): + return object_list( + request, + queryset=Document.objects.all(), + template_name='generic_list.html', + extra_context={ + 'title':_(u'documents'), + 'extra_columns':[ + {'name':_(u'filename'), 'attribute':'file_filename'}, + {'name':_(u'extension'), 'attribute':'file_extension'}, + {'name':_(u'mimetype'), 'attribute':'file_mimetype'}, + {'name':_(u'added'), 'attribute':'date_added'}, + ], + }, + ) + + +def document_create(request): + MetadataFormSet = formset_factory(MetadataForm, extra=0) + wizard = DocumentCreateWizard(form_list=[DocumentTypeSelectForm, MetadataFormSet]) + return wizard(request) + + +def upload_document_with_type(request, document_type_id): + document_type = get_object_or_404(DocumentType, pk=document_type_id) + if request.method == 'POST': + form = DocumentForm(request.POST, request.FILES, initial={'document_type':document_type}) + if form.is_valid(): + instance = form.save() + for key, value in request.GET.items(): + document_metadata = DocumentMetadata( + document=instance, + metadata_type=get_object_or_404(MetadataType, pk=key), + value=value + ) + document_metadata.save() + messages.success(request, _(u'Document uploaded successfully.')) + return HttpResponseRedirect(reverse('document_list')) + else: + form = DocumentForm(initial={'document_type':document_type}) + + return render_to_response('generic_form.html', { + 'form':form + }, context_instance=RequestContext(request)) + + + diff --git a/apps/main/__init__.py b/apps/main/__init__.py new file mode 100644 index 0000000000..e610bb5d76 --- /dev/null +++ b/apps/main/__init__.py @@ -0,0 +1,13 @@ +from django.utils.translation import ugettext_lazy as _ + +from common.api import register_menu + + +register_menu([ + {'text':_(u'home'), 'view':'home', 'famfam':'house', 'position':0}, + + {'text':_(u'setup'), 'view':'', 'links': [ + ],'famfam':'cog', 'name':'setup','position':7}, + + {'text':_(u'about'), 'view':'about', 'position':8}, +]) diff --git a/apps/main/models.py b/apps/main/models.py new file mode 100644 index 0000000000..71a8362390 --- /dev/null +++ b/apps/main/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/apps/main/templates/about.html b/apps/main/templates/about.html new file mode 100755 index 0000000000..f65e2901d1 --- /dev/null +++ b/apps/main/templates/about.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{% load i18n %} +{% load project_tags %} +{% block title %} :: {% trans 'About this program' %}{% endblock %} +{% block content %} + +
    +

    + {% project_name %}

    + {% trans 'Django based document manager with custom metadata indexing and samba file serving integration' %}

    + http://www.github.com/rosarior/mayan/

    +

    +
    +{% endblock %} +{% block footer %} + +{% endblock %} diff --git a/apps/main/templates/base.html b/apps/main/templates/base.html new file mode 100755 index 0000000000..ee0684b2b9 --- /dev/null +++ b/apps/main/templates/base.html @@ -0,0 +1,102 @@ +{% extends "web_theme_base.html" %} +{% load i18n %} +{% load project_tags %} +{% load navigation %} + +{% block html_title %}{% project_name %}{% block title %}{% endblock %}{% endblock %} + +{% block web_theme_project_name %}{% project_name %}{% endblock %} + +{% block web_theme_stylesheets %} + + + {% block stylesheets %}{% endblock %} +{% endblock %} + +{% block web_theme_user_navigation %} +
  • {% trans 'User' %}: + {% if user.is_anonymous %} + {% trans 'Anonymous' %} + {% else %} + {{ user }} + ({% trans 'New password' %}) + {% endif %} +
  • + {% if user.is_staff %} +
  • {% trans "Admin site" %}
  • + {% endif %} + + +
  • +
    {% csrf_token %} + + +
    +
  • +
  • {% if user.is_anonymous %}{% trans 'Login' %}{% else %}{% trans 'Logout' %}{% endif %}
  • +{% endblock %} + +{% block web_theme_main_navigation %} + {% main_navigation %} + {% for link in navigation_main_links %} +
  • {{ link.text|capfirst }}{% if link.famfam %}{% endif %}
  • + {% endfor %} +{% endblock %} + +{% block web_theme_secondary_navigation %} + {% main_navigation %} + {% if navigation_secondary_links %} +
    + +
    + {% endif %} +{% endblock %} + +{% block web_theme_sidebar %} + {% get_object_navigation_links %} + {% if object_navigation_links %} +
    + {% if object %} + {% if object_name %} +

    {% blocktrans %}Actions for {{ object_name }}: {{ object }}{% endblocktrans %}

    + {% else %} +

    {% blocktrans %}Actions for: {{ object }}{% endblocktrans %}

    + {% endif %} + {% else %} +

    }{% trans 'Actions' %}

    + {% endif %} + +
    + {% endif %} + + {% get_object_navigation_links "sidebar" %} + {% if object_navigation_links %} +
    +

    {% trans 'Other available actions' %}

    + +
    + {% endif %} + + {% block sidebar %}{% endblock %} +{% endblock %} + + +{% block web_theme_content %}{% block content %}{% endblock %}{% endblock %} + +{% block web_theme_footer %}{% block footer %}{% endblock %}{% endblock %} diff --git a/apps/main/templates/home.html b/apps/main/templates/home.html new file mode 100755 index 0000000000..0568a85830 --- /dev/null +++ b/apps/main/templates/home.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} +{% load project_tags %} +{% load i18n %} +{% block content %} +
    +

    {% project_name %}

    +
    +
    +{% endblock %} +{% block footer %} + +{% endblock %} diff --git a/apps/main/tests.py b/apps/main/tests.py new file mode 100644 index 0000000000..2247054b35 --- /dev/null +++ b/apps/main/tests.py @@ -0,0 +1,23 @@ +""" +This file demonstrates two different styles of tests (one doctest and one +unittest). These will both pass when you run "manage.py test". + +Replace these with more appropriate tests for your application. +""" + +from django.test import TestCase + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.failUnlessEqual(1 + 1, 2) + +__test__ = {"doctest": """ +Another way to test that 1 + 1 is equal to 2. + +>>> 1 + 1 == 2 +True +"""} + diff --git a/apps/main/urls.py b/apps/main/urls.py new file mode 100644 index 0000000000..8a6065a5b5 --- /dev/null +++ b/apps/main/urls.py @@ -0,0 +1,6 @@ +from django.conf.urls.defaults import * + + +urlpatterns = patterns('main.views', + url(r'^$', 'home', (), 'home'), +) diff --git a/apps/main/views.py b/apps/main/views.py new file mode 100644 index 0000000000..b212599acf --- /dev/null +++ b/apps/main/views.py @@ -0,0 +1,6 @@ +from django.shortcuts import render_to_response +from django.template import RequestContext + +def home(request): + return render_to_response('home.html', {}, + context_instance=RequestContext(request)) diff --git a/apps/web_theme/__init__.py b/apps/web_theme/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/web_theme/conf/__init__.py b/apps/web_theme/conf/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/web_theme/conf/settings.py b/apps/web_theme/conf/settings.py new file mode 100644 index 0000000000..36ef9d7e5e --- /dev/null +++ b/apps/web_theme/conf/settings.py @@ -0,0 +1,7 @@ +from django.conf import settings + +#Theme options are: +#amro, bec, bec-green, blue, default, djime-cerulean, drastic-dark, +#kathleene, olive, orange, red, reidb-greenish, warehouse + +THEME = getattr(settings, 'WEB_THEME', 'default') diff --git a/apps/web_theme/locale/es/LC_MESSAGES/django.mo b/apps/web_theme/locale/es/LC_MESSAGES/django.mo new file mode 100644 index 0000000000..5b2b6632f6 Binary files /dev/null and b/apps/web_theme/locale/es/LC_MESSAGES/django.mo differ diff --git a/apps/web_theme/locale/es/LC_MESSAGES/django.po b/apps/web_theme/locale/es/LC_MESSAGES/django.po new file mode 100644 index 0000000000..f70686b491 --- /dev/null +++ b/apps/web_theme/locale/es/LC_MESSAGES/django.po @@ -0,0 +1,24 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-01-28 09:43-0400\n" +"PO-Revision-Date: 2011-01-28 09:43\n" +"Last-Translator: \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: \n" +"X-Translated-Using: django-rosetta 0.5.6\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: templates/web_theme_login.html:3 templates/web_theme_login.html.py:8 +msgid "Login" +msgstr "Iniciar sesión" diff --git a/apps/web_theme/locale/ru/LC_MESSAGES/django.mo b/apps/web_theme/locale/ru/LC_MESSAGES/django.mo new file mode 100644 index 0000000000..5f31b44d88 Binary files /dev/null and b/apps/web_theme/locale/ru/LC_MESSAGES/django.mo differ diff --git a/apps/web_theme/locale/ru/LC_MESSAGES/django.po b/apps/web_theme/locale/ru/LC_MESSAGES/django.po new file mode 100644 index 0000000000..303d9e09e3 --- /dev/null +++ b/apps/web_theme/locale/ru/LC_MESSAGES/django.po @@ -0,0 +1,24 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-01-30 16:51+0300\n" +"PO-Revision-Date: 2011-01-30 13:12\n" +"Last-Translator: \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: \n" +"X-Translated-Using: django-rosetta 0.5.5\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#: templates/web_theme_login.html:3 templates/web_theme_login.html.py:8 +msgid "Login" +msgstr "Пользователь" diff --git a/apps/web_theme/media b/apps/web_theme/media new file mode 160000 index 0000000000..c4159791f9 --- /dev/null +++ b/apps/web_theme/media @@ -0,0 +1 @@ +Subproject commit c4159791f935311e800303a80e7deef0e7b99d21 diff --git a/apps/web_theme/models.py b/apps/web_theme/models.py new file mode 100644 index 0000000000..71a8362390 --- /dev/null +++ b/apps/web_theme/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/apps/web_theme/templates/pagination/pagination.html b/apps/web_theme/templates/pagination/pagination.html new file mode 100644 index 0000000000..b8122b55f8 --- /dev/null +++ b/apps/web_theme/templates/pagination/pagination.html @@ -0,0 +1,33 @@ +{% if is_paginated %} +{% load i18n %} +
    + +
    + +{% endif %} diff --git a/apps/web_theme/templates/web_theme_base.html b/apps/web_theme/templates/web_theme_base.html new file mode 100644 index 0000000000..4266181929 --- /dev/null +++ b/apps/web_theme/templates/web_theme_base.html @@ -0,0 +1,72 @@ +{% load i18n %} +{% load theme_tags %} +{% get_theme as web_theme %} + + + + + + + {% block html_title %}{% endblock %} + + {% block keywords %}{% endblock %} + + + + {% block web_theme_stylesheets %}{% endblock %} + + + + + {% block web_theme_javascript %}{% endblock %} + + +
    + {% if user.is_anonymous %} +
    + {% block content_plain %}{% endblock %} +
    + {% endif %} + {% if not user.is_anonymous %} + +
    +
    +
    + {% block web_theme_secondary_navigation %}{% endblock %} + {% if messages %} +
    +
    + {% for message in messages %} +
    +

    {{ message }}

    +
    + {% endfor %} +
    +
    + {% endif %} + {% block web_theme_messages %}{% endblock %} + {% block web_theme_content %}{% endblock %} +
    + {% block web_theme_footer %}{% endblock %} +
    + +
    + {% endif %} +
    + + diff --git a/apps/web_theme/templates/web_theme_login.html b/apps/web_theme/templates/web_theme_login.html new file mode 100644 index 0000000000..b5d1e39c79 --- /dev/null +++ b/apps/web_theme/templates/web_theme_login.html @@ -0,0 +1,23 @@ +{% extends "web_theme_base.html" %} +{% load i18n %} +{% block html_title %}{% trans "Login" %}{% endblock %} +{% block content_plain %} +
    +

    {% block project_name %}{% endblock %}

    +
    +

    {% trans "Login" %}

    + +
    +{% endblock %} diff --git a/apps/web_theme/templatetags/__init__.py b/apps/web_theme/templatetags/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/web_theme/templatetags/styling.py b/apps/web_theme/templatetags/styling.py new file mode 100644 index 0000000000..a9b7adf5c4 --- /dev/null +++ b/apps/web_theme/templatetags/styling.py @@ -0,0 +1,32 @@ +from django import forms +from django.template import TemplateSyntaxError, Library, \ + VariableDoesNotExist, Node, Variable +from django.conf import settings + +register = Library() + + +class StylingNode(Node): + def __init__(self, form_name, *args, **kwargs): + self.form_name = form_name + + def render(self, context): + form = Variable(self.form_name).resolve(context) + for field_name, field in form.fields.items(): + + if isinstance(field.widget, forms.widgets.TextInput): + field.widget.attrs['class'] = 'text_field' + elif isinstance(field.widget, forms.widgets.PasswordInput): + field.widget.attrs['class'] = 'text_field' + elif isinstance(field.widget, forms.widgets.Textarea): + field.widget.attrs['class'] = 'text_area' + + context[self.form_name] = form + return '' + + + +@register.tag +def add_classes_to_form(parser, token): + args = token.split_contents() + return StylingNode(args[1]) diff --git a/apps/web_theme/templatetags/theme_tags.py b/apps/web_theme/templatetags/theme_tags.py new file mode 100644 index 0000000000..4661008f31 --- /dev/null +++ b/apps/web_theme/templatetags/theme_tags.py @@ -0,0 +1,44 @@ +import types + +from django.conf import settings +from django.core.urlresolvers import reverse, NoReverseMatch +from django.core.urlresolvers import RegexURLResolver, RegexURLPattern, Resolver404, get_resolver +from django.template import TemplateSyntaxError, Library, \ + VariableDoesNotExist, Node, Variable +from django.utils.text import unescape_string_literal + +#from common.api import object_navigation +from web_theme.conf import settings as web_theme_settings + +register = Library() + + +class GetThemeNode(Node): + def __init__(self, var_name, *args): + self.var_name = var_name + + def render(self, context): + context['web_theme'] = web_theme_settings.THEME + return '' + + +import re + +@register.tag +def get_theme(parser, token): + try: + # Splitting by None == splitting by spaces. + tag_name, arg = token.contents.split(None, 1) + except ValueError: + raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents.split()[0] + + #m = re.search(r'(.*?) as (\w+)', arg) + m = re.search(r'as (\w+)', arg) + if not m: + raise template.TemplateSyntaxError, "%r tag had invalid arguments" % tag_name + #format_string, var_name = m.groups() + var_name = m.groups() + + #if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")): + # raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name + return GetThemeNode(var_name) diff --git a/apps/web_theme/tests.py b/apps/web_theme/tests.py new file mode 100644 index 0000000000..2247054b35 --- /dev/null +++ b/apps/web_theme/tests.py @@ -0,0 +1,23 @@ +""" +This file demonstrates two different styles of tests (one doctest and one +unittest). These will both pass when you run "manage.py test". + +Replace these with more appropriate tests for your application. +""" + +from django.test import TestCase + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.failUnlessEqual(1 + 1, 2) + +__test__ = {"doctest": """ +Another way to test that 1 + 1 is equal to 2. + +>>> 1 + 1 == 2 +True +"""} + diff --git a/apps/web_theme/views.py b/apps/web_theme/views.py new file mode 100644 index 0000000000..60f00ef0ef --- /dev/null +++ b/apps/web_theme/views.py @@ -0,0 +1 @@ +# Create your views here. diff --git a/docs/TODO b/docs/TODO new file mode 100644 index 0000000000..aea674cfe0 --- /dev/null +++ b/docs/TODO @@ -0,0 +1,6 @@ +* Filter by metadata +* Jquery upload document upload form with ajax widget +* Filterform date filtering widget +* Create indexing filesystem folders from document type metadata type +* Validate GET data before saving file +* Handle NULL mimetypes during model save diff --git a/runserver.sh b/runserver.sh new file mode 100755 index 0000000000..ac9583265e --- /dev/null +++ b/runserver.sh @@ -0,0 +1,6 @@ +#!/bin/sh +if [ -n "$1" ]; then + ./manage.py runserver $1 --adminmedia ./site_media/admin_media/ +else + ./manage.py runserver --adminmedia ./site_media/admin_media/ +fi diff --git a/runserver_plus.sh b/runserver_plus.sh new file mode 100755 index 0000000000..5be5b13db6 --- /dev/null +++ b/runserver_plus.sh @@ -0,0 +1,6 @@ +#!/bin/sh +if [ -n "$1" ]; then + ./manage.py runserver_plus $1 --adminmedia ./site_media/admin_media/ +else + ./manage.py runserver_plus --adminmedia ./site_media/admin_media/ +fi diff --git a/settings.py b/settings.py index 511c905e09..0b6875acad 100644 --- a/settings.py +++ b/settings.py @@ -95,6 +95,7 @@ MIDDLEWARE_CLASSES = ( 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', + 'pagination.middleware.PaginationMiddleware', ) ROOT_URLCONF = 'urls' @@ -115,7 +116,11 @@ INSTALLED_APPS = ( 'django.contrib.messages', 'django.contrib.admin', 'django.contrib.admindocs', + 'web_theme', + 'main', + 'common', 'documents', + 'pagination', ) TEMPLATE_CONTEXT_PROCESSORS = ( diff --git a/site_media/css/famfamfam-silk-sprite.css b/site_media/css/famfamfam-silk-sprite.css new file mode 100644 index 0000000000..64cddede92 --- /dev/null +++ b/site_media/css/famfamfam-silk-sprite.css @@ -0,0 +1,1007 @@ +/* icon set header - required*/ +.famfam {vertical-align: middle; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; display: inline-block; width: 20px; height: 20px;} +.famfam.active {background-image: url('../images/famfamfam-silk-sprites/famfam-active.png'); cursor:pointer;} +/* .famfam.hover{background-image: url('../images/famfamfam-silk-sprites/famfam-hover.png'); cursor:pointer;} */ +.famfam.inactive{background-image: url('../images/famfamfam-silk-sprites/famfam-inactive.png'); cursor:default;} + +/* icon set items - include only the rules for the icons you wish to use in your page*/ +.famfam-accept {background-position: -0px -0px;} +.famfam-add {background-position: -20px -0px;} +.famfam-anchor {background-position: -40px -0px;} +.famfam-application {background-position: -60px -0px;} +.famfam-application_add {background-position: -80px -0px;} +.famfam-application_cascade {background-position: -100px -0px;} +.famfam-application_delete {background-position: -120px -0px;} +.famfam-application_double {background-position: -140px -0px;} +.famfam-application_edit {background-position: -160px -0px;} +.famfam-application_error {background-position: -180px -0px;} +.famfam-application_form {background-position: -200px -0px;} +.famfam-application_form_add {background-position: -220px -0px;} +.famfam-application_form_delete {background-position: -240px -0px;} +.famfam-application_form_edit {background-position: -260px -0px;} +.famfam-application_form_magnify {background-position: -280px -0px;} +.famfam-application_get {background-position: -300px -0px;} +.famfam-application_go {background-position: -320px -0px;} +.famfam-application_home {background-position: -340px -0px;} +.famfam-application_key {background-position: -360px -0px;} +.famfam-application_lightning {background-position: -380px -0px;} +.famfam-application_link {background-position: -400px -0px;} +.famfam-application_osx {background-position: -420px -0px;} +.famfam-application_osx_terminal {background-position: -440px -0px;} +.famfam-application_put {background-position: -460px -0px;} +.famfam-application_side_boxes {background-position: -480px -0px;} +.famfam-application_side_contract {background-position: -500px -0px;} +.famfam-application_side_expand {background-position: -520px -0px;} +.famfam-application_side_list {background-position: -540px -0px;} +.famfam-application_side_tree {background-position: -560px -0px;} +.famfam-application_split {background-position: -580px -0px;} +.famfam-application_tile_horizontal {background-position: -600px -0px;} +.famfam-application_tile_vertical {background-position: -620px -0px;} +.famfam-application_view_columns {background-position: -640px -0px;} +.famfam-application_view_detail {background-position: -660px -0px;} +.famfam-application_view_gallery {background-position: -680px -0px;} +.famfam-application_view_icons {background-position: -700px -0px;} +.famfam-application_view_list {background-position: -720px -0px;} +.famfam-application_view_tile {background-position: -740px -0px;} +.famfam-application_xp {background-position: -760px -0px;} +.famfam-application_xp_terminal {background-position: -780px -0px;} +.famfam-arrow_branch {background-position: -0px -20px;} +.famfam-arrow_divide {background-position: -20px -20px;} +.famfam-arrow_down {background-position: -40px -20px;} +.famfam-arrow_in {background-position: -60px -20px;} +.famfam-arrow_inout {background-position: -80px -20px;} +.famfam-arrow_join {background-position: -100px -20px;} +.famfam-arrow_left {background-position: -120px -20px;} +.famfam-arrow_merge {background-position: -140px -20px;} +.famfam-arrow_out {background-position: -160px -20px;} +.famfam-arrow_redo {background-position: -180px -20px;} +.famfam-arrow_refresh {background-position: -200px -20px;} +.famfam-arrow_refresh_small {background-position: -220px -20px;} +.famfam-arrow_right {background-position: -240px -20px;} +.famfam-arrow_rotate_anticlockwise {background-position: -260px -20px;} +.famfam-arrow_rotate_clockwise {background-position: -280px -20px;} +.famfam-arrow_switch {background-position: -300px -20px;} +.famfam-arrow_turn_left {background-position: -320px -20px;} +.famfam-arrow_turn_right {background-position: -340px -20px;} +.famfam-arrow_undo {background-position: -360px -20px;} +.famfam-arrow_up {background-position: -380px -20px;} +.famfam-asterisk_orange {background-position: -400px -20px;} +.famfam-asterisk_yellow {background-position: -420px -20px;} +.famfam-attach {background-position: -440px -20px;} +.famfam-award_star_add {background-position: -460px -20px;} +.famfam-award_star_bronze_1 {background-position: -480px -20px;} +.famfam-award_star_bronze_2 {background-position: -500px -20px;} +.famfam-award_star_bronze_3 {background-position: -520px -20px;} +.famfam-award_star_delete {background-position: -540px -20px;} +.famfam-award_star_gold_1 {background-position: -560px -20px;} +.famfam-award_star_gold_2 {background-position: -580px -20px;} +.famfam-award_star_gold_3 {background-position: -600px -20px;} +.famfam-award_star_silver_1 {background-position: -620px -20px;} +.famfam-award_star_silver_2 {background-position: -640px -20px;} +.famfam-award_star_silver_3 {background-position: -660px -20px;} +.famfam-basket {background-position: -680px -20px;} +.famfam-basket_add {background-position: -700px -20px;} +.famfam-basket_delete {background-position: -720px -20px;} +.famfam-basket_edit {background-position: -740px -20px;} +.famfam-basket_error {background-position: -760px -20px;} +.famfam-basket_go {background-position: -780px -20px;} +.famfam-basket_put {background-position: -0px -40px;} +.famfam-basket_remove {background-position: -20px -40px;} +.famfam-bell {background-position: -40px -40px;} +.famfam-bell_add {background-position: -60px -40px;} +.famfam-bell_delete {background-position: -80px -40px;} +.famfam-bell_error {background-position: -100px -40px;} +.famfam-bell_go {background-position: -120px -40px;} +.famfam-bell_link {background-position: -140px -40px;} +.famfam-bin {background-position: -160px -40px;} +.famfam-bin_closed {background-position: -180px -40px;} +.famfam-bin_empty {background-position: -200px -40px;} +.famfam-bomb {background-position: -220px -40px;} +.famfam-book {background-position: -240px -40px;} +.famfam-book_add {background-position: -260px -40px;} +.famfam-book_addresses {background-position: -280px -40px;} +.famfam-book_delete {background-position: -300px -40px;} +.famfam-book_edit {background-position: -320px -40px;} +.famfam-book_error {background-position: -340px -40px;} +.famfam-book_go {background-position: -360px -40px;} +.famfam-book_key {background-position: -380px -40px;} +.famfam-book_link {background-position: -400px -40px;} +.famfam-book_next {background-position: -420px -40px;} +.famfam-book_open {background-position: -440px -40px;} +.famfam-book_previous {background-position: -460px -40px;} +.famfam-box {background-position: -480px -40px;} +.famfam-brick {background-position: -500px -40px;} +.famfam-brick_add {background-position: -520px -40px;} +.famfam-brick_delete {background-position: -540px -40px;} +.famfam-brick_edit {background-position: -560px -40px;} +.famfam-brick_error {background-position: -580px -40px;} +.famfam-brick_go {background-position: -600px -40px;} +.famfam-brick_link {background-position: -620px -40px;} +.famfam-bricks {background-position: -640px -40px;} +.famfam-briefcase {background-position: -660px -40px;} +.famfam-bug {background-position: -680px -40px;} +.famfam-bug_add {background-position: -700px -40px;} +.famfam-bug_delete {background-position: -720px -40px;} +.famfam-bug_edit {background-position: -740px -40px;} +.famfam-bug_error {background-position: -760px -40px;} +.famfam-bug_go {background-position: -780px -40px;} +.famfam-bug_link {background-position: -0px -60px;} +.famfam-building {background-position: -20px -60px;} +.famfam-building_add {background-position: -40px -60px;} +.famfam-building_delete {background-position: -60px -60px;} +.famfam-building_edit {background-position: -80px -60px;} +.famfam-building_error {background-position: -100px -60px;} +.famfam-building_go {background-position: -120px -60px;} +.famfam-building_key {background-position: -140px -60px;} +.famfam-building_link {background-position: -160px -60px;} +.famfam-bullet_add {background-position: -180px -60px;} +.famfam-bullet_arrow_bottom {background-position: -200px -60px;} +.famfam-bullet_arrow_down {background-position: -220px -60px;} +.famfam-bullet_arrow_top {background-position: -240px -60px;} +.famfam-bullet_arrow_up {background-position: -260px -60px;} +.famfam-bullet_black {background-position: -280px -60px;} +.famfam-bullet_blue {background-position: -300px -60px;} +.famfam-bullet_delete {background-position: -320px -60px;} +.famfam-bullet_disk {background-position: -340px -60px;} +.famfam-bullet_error {background-position: -360px -60px;} +.famfam-bullet_feed {background-position: -380px -60px;} +.famfam-bullet_go {background-position: -400px -60px;} +.famfam-bullet_green {background-position: -420px -60px;} +.famfam-bullet_key {background-position: -440px -60px;} +.famfam-bullet_orange {background-position: -460px -60px;} +.famfam-bullet_picture {background-position: -480px -60px;} +.famfam-bullet_pink {background-position: -500px -60px;} +.famfam-bullet_purple {background-position: -520px -60px;} +.famfam-bullet_red {background-position: -540px -60px;} +.famfam-bullet_star {background-position: -560px -60px;} +.famfam-bullet_toggle_minus {background-position: -580px -60px;} +.famfam-bullet_toggle_plus {background-position: -600px -60px;} +.famfam-bullet_white {background-position: -620px -60px;} +.famfam-bullet_wrench {background-position: -640px -60px;} +.famfam-bullet_yellow {background-position: -660px -60px;} +.famfam-cake {background-position: -680px -60px;} +.famfam-calculator {background-position: -700px -60px;} +.famfam-calculator_add {background-position: -720px -60px;} +.famfam-calculator_delete {background-position: -740px -60px;} +.famfam-calculator_edit {background-position: -760px -60px;} +.famfam-calculator_error {background-position: -780px -60px;} +.famfam-calculator_link {background-position: -0px -80px;} +.famfam-calendar {background-position: -20px -80px;} +.famfam-calendar_add {background-position: -40px -80px;} +.famfam-calendar_delete {background-position: -60px -80px;} +.famfam-calendar_edit {background-position: -80px -80px;} +.famfam-calendar_link {background-position: -100px -80px;} +.famfam-calendar_view_day {background-position: -120px -80px;} +.famfam-calendar_view_month {background-position: -140px -80px;} +.famfam-calendar_view_week {background-position: -160px -80px;} +.famfam-camera {background-position: -180px -80px;} +.famfam-camera_add {background-position: -200px -80px;} +.famfam-camera_delete {background-position: -220px -80px;} +.famfam-camera_edit {background-position: -240px -80px;} +.famfam-camera_error {background-position: -260px -80px;} +.famfam-camera_go {background-position: -280px -80px;} +.famfam-camera_link {background-position: -300px -80px;} +.famfam-camera_small {background-position: -320px -80px;} +.famfam-cancel {background-position: -340px -80px;} +.famfam-car {background-position: -360px -80px;} +.famfam-car_add {background-position: -380px -80px;} +.famfam-car_delete {background-position: -400px -80px;} +.famfam-cart {background-position: -420px -80px;} +.famfam-cart_add {background-position: -440px -80px;} +.famfam-cart_delete {background-position: -460px -80px;} +.famfam-cart_edit {background-position: -480px -80px;} +.famfam-cart_error {background-position: -500px -80px;} +.famfam-cart_go {background-position: -520px -80px;} +.famfam-cart_put {background-position: -540px -80px;} +.famfam-cart_remove {background-position: -560px -80px;} +.famfam-cd {background-position: -580px -80px;} +.famfam-cd_add {background-position: -600px -80px;} +.famfam-cd_burn {background-position: -620px -80px;} +.famfam-cd_delete {background-position: -640px -80px;} +.famfam-cd_edit {background-position: -660px -80px;} +.famfam-cd_eject {background-position: -680px -80px;} +.famfam-cd_go {background-position: -700px -80px;} +.famfam-chart_bar {background-position: -720px -80px;} +.famfam-chart_bar_add {background-position: -740px -80px;} +.famfam-chart_bar_delete {background-position: -760px -80px;} +.famfam-chart_bar_edit {background-position: -780px -80px;} +.famfam-chart_bar_error {background-position: -0px -100px;} +.famfam-chart_bar_link {background-position: -20px -100px;} +.famfam-chart_curve {background-position: -40px -100px;} +.famfam-chart_curve_add {background-position: -60px -100px;} +.famfam-chart_curve_delete {background-position: -80px -100px;} +.famfam-chart_curve_edit {background-position: -100px -100px;} +.famfam-chart_curve_error {background-position: -120px -100px;} +.famfam-chart_curve_go {background-position: -140px -100px;} +.famfam-chart_curve_link {background-position: -160px -100px;} +.famfam-chart_line {background-position: -180px -100px;} +.famfam-chart_line_add {background-position: -200px -100px;} +.famfam-chart_line_delete {background-position: -220px -100px;} +.famfam-chart_line_edit {background-position: -240px -100px;} +.famfam-chart_line_error {background-position: -260px -100px;} +.famfam-chart_line_link {background-position: -280px -100px;} +.famfam-chart_organisation {background-position: -300px -100px;} +.famfam-chart_organisation_add {background-position: -320px -100px;} +.famfam-chart_organisation_delete {background-position: -340px -100px;} +.famfam-chart_pie {background-position: -360px -100px;} +.famfam-chart_pie_add {background-position: -380px -100px;} +.famfam-chart_pie_delete {background-position: -400px -100px;} +.famfam-chart_pie_edit {background-position: -420px -100px;} +.famfam-chart_pie_error {background-position: -440px -100px;} +.famfam-chart_pie_link {background-position: -460px -100px;} +.famfam-clock {background-position: -480px -100px;} +.famfam-clock_add {background-position: -500px -100px;} +.famfam-clock_delete {background-position: -520px -100px;} +.famfam-clock_edit {background-position: -540px -100px;} +.famfam-clock_error {background-position: -560px -100px;} +.famfam-clock_go {background-position: -580px -100px;} +.famfam-clock_link {background-position: -600px -100px;} +.famfam-clock_pause {background-position: -620px -100px;} +.famfam-clock_play {background-position: -640px -100px;} +.famfam-clock_red {background-position: -660px -100px;} +.famfam-clock_stop {background-position: -680px -100px;} +.famfam-cog {background-position: -700px -100px;} +.famfam-cog_add {background-position: -720px -100px;} +.famfam-cog_delete {background-position: -740px -100px;} +.famfam-cog_edit {background-position: -760px -100px;} +.famfam-cog_error {background-position: -780px -100px;} +.famfam-cog_go {background-position: -0px -120px;} +.famfam-coins {background-position: -20px -120px;} +.famfam-coins_add {background-position: -40px -120px;} +.famfam-coins_delete {background-position: -60px -120px;} +.famfam-color_swatch {background-position: -80px -120px;} +.famfam-color_wheel {background-position: -100px -120px;} +.famfam-comment {background-position: -120px -120px;} +.famfam-comment_add {background-position: -140px -120px;} +.famfam-comment_delete {background-position: -160px -120px;} +.famfam-comment_edit {background-position: -180px -120px;} +.famfam-comments {background-position: -200px -120px;} +.famfam-comments_add {background-position: -220px -120px;} +.famfam-comments_delete {background-position: -240px -120px;} +.famfam-compress {background-position: -260px -120px;} +.famfam-computer {background-position: -280px -120px;} +.famfam-computer_add {background-position: -300px -120px;} +.famfam-computer_delete {background-position: -320px -120px;} +.famfam-computer_edit {background-position: -340px -120px;} +.famfam-computer_error {background-position: -360px -120px;} +.famfam-computer_go {background-position: -380px -120px;} +.famfam-computer_key {background-position: -400px -120px;} +.famfam-computer_link {background-position: -420px -120px;} +.famfam-connect {background-position: -440px -120px;} +.famfam-contrast {background-position: -460px -120px;} +.famfam-contrast_decrease {background-position: -480px -120px;} +.famfam-contrast_high {background-position: -500px -120px;} +.famfam-contrast_increase {background-position: -520px -120px;} +.famfam-contrast_low {background-position: -540px -120px;} +.famfam-control_eject {background-position: -560px -120px;} +.famfam-control_eject_blue {background-position: -580px -120px;} +.famfam-control_end {background-position: -600px -120px;} +.famfam-control_end_blue {background-position: -620px -120px;} +.famfam-control_equalizer {background-position: -640px -120px;} +.famfam-control_equalizer_blue {background-position: -660px -120px;} +.famfam-control_fastforward {background-position: -680px -120px;} +.famfam-control_fastforward_blue {background-position: -700px -120px;} +.famfam-control_pause {background-position: -720px -120px;} +.famfam-control_pause_blue {background-position: -740px -120px;} +.famfam-control_play {background-position: -760px -120px;} +.famfam-control_play_blue {background-position: -780px -120px;} +.famfam-control_repeat {background-position: -0px -140px;} +.famfam-control_repeat_blue {background-position: -20px -140px;} +.famfam-control_rewind {background-position: -40px -140px;} +.famfam-control_rewind_blue {background-position: -60px -140px;} +.famfam-control_start {background-position: -80px -140px;} +.famfam-control_start_blue {background-position: -100px -140px;} +.famfam-control_stop {background-position: -120px -140px;} +.famfam-control_stop_blue {background-position: -140px -140px;} +.famfam-controller {background-position: -160px -140px;} +.famfam-controller_add {background-position: -180px -140px;} +.famfam-controller_delete {background-position: -200px -140px;} +.famfam-controller_error {background-position: -220px -140px;} +.famfam-creditcards {background-position: -240px -140px;} +.famfam-cross {background-position: -260px -140px;} +.famfam-css {background-position: -280px -140px;} +.famfam-css_add {background-position: -300px -140px;} +.famfam-css_delete {background-position: -320px -140px;} +.famfam-css_go {background-position: -340px -140px;} +.famfam-css_valid {background-position: -360px -140px;} +.famfam-cup {background-position: -380px -140px;} +.famfam-cup_add {background-position: -400px -140px;} +.famfam-cup_delete {background-position: -420px -140px;} +.famfam-cup_edit {background-position: -440px -140px;} +.famfam-cup_error {background-position: -460px -140px;} +.famfam-cup_go {background-position: -480px -140px;} +.famfam-cup_key {background-position: -500px -140px;} +.famfam-cup_link {background-position: -520px -140px;} +.famfam-cursor {background-position: -540px -140px;} +.famfam-cut {background-position: -560px -140px;} +.famfam-cut_red {background-position: -580px -140px;} +.famfam-database {background-position: -600px -140px;} +.famfam-database_add {background-position: -620px -140px;} +.famfam-database_connect {background-position: -640px -140px;} +.famfam-database_delete {background-position: -660px -140px;} +.famfam-database_edit {background-position: -680px -140px;} +.famfam-database_error {background-position: -700px -140px;} +.famfam-database_gear {background-position: -720px -140px;} +.famfam-database_go {background-position: -740px -140px;} +.famfam-database_key {background-position: -760px -140px;} +.famfam-database_lightning {background-position: -780px -140px;} +.famfam-database_link {background-position: -0px -160px;} +.famfam-database_refresh {background-position: -20px -160px;} +.famfam-database_save {background-position: -40px -160px;} +.famfam-database_table {background-position: -60px -160px;} +.famfam-date {background-position: -80px -160px;} +.famfam-date_add {background-position: -100px -160px;} +.famfam-date_delete {background-position: -120px -160px;} +.famfam-date_edit {background-position: -140px -160px;} +.famfam-date_error {background-position: -160px -160px;} +.famfam-date_go {background-position: -180px -160px;} +.famfam-date_link {background-position: -200px -160px;} +.famfam-date_magnify {background-position: -220px -160px;} +.famfam-date_next {background-position: -240px -160px;} +.famfam-date_previous {background-position: -260px -160px;} +.famfam-delete {background-position: -280px -160px;} +.famfam-disconnect {background-position: -300px -160px;} +.famfam-disk {background-position: -320px -160px;} +.famfam-disk_multiple {background-position: -340px -160px;} +.famfam-door {background-position: -360px -160px;} +.famfam-door_in {background-position: -380px -160px;} +.famfam-door_open {background-position: -400px -160px;} +.famfam-door_out {background-position: -420px -160px;} +.famfam-drink {background-position: -440px -160px;} +.famfam-drink_empty {background-position: -460px -160px;} +.famfam-drive {background-position: -480px -160px;} +.famfam-drive_add {background-position: -500px -160px;} +.famfam-drive_burn {background-position: -520px -160px;} +.famfam-drive_cd {background-position: -540px -160px;} +.famfam-drive_cd_empty {background-position: -560px -160px;} +.famfam-drive_delete {background-position: -580px -160px;} +.famfam-drive_disk {background-position: -600px -160px;} +.famfam-drive_edit {background-position: -620px -160px;} +.famfam-drive_error {background-position: -640px -160px;} +.famfam-drive_go {background-position: -660px -160px;} +.famfam-drive_key {background-position: -680px -160px;} +.famfam-drive_link {background-position: -700px -160px;} +.famfam-drive_magnify {background-position: -720px -160px;} +.famfam-drive_network {background-position: -740px -160px;} +.famfam-drive_rename {background-position: -760px -160px;} +.famfam-drive_user {background-position: -780px -160px;} +.famfam-drive_web {background-position: -0px -180px;} +.famfam-dvd {background-position: -20px -180px;} +.famfam-dvd_add {background-position: -40px -180px;} +.famfam-dvd_delete {background-position: -60px -180px;} +.famfam-dvd_edit {background-position: -80px -180px;} +.famfam-dvd_error {background-position: -100px -180px;} +.famfam-dvd_go {background-position: -120px -180px;} +.famfam-dvd_key {background-position: -140px -180px;} +.famfam-dvd_link {background-position: -160px -180px;} +.famfam-email {background-position: -180px -180px;} +.famfam-email_add {background-position: -200px -180px;} +.famfam-email_attach {background-position: -220px -180px;} +.famfam-email_delete {background-position: -240px -180px;} +.famfam-email_edit {background-position: -260px -180px;} +.famfam-email_error {background-position: -280px -180px;} +.famfam-email_go {background-position: -300px -180px;} +.famfam-email_link {background-position: -320px -180px;} +.famfam-email_open {background-position: -340px -180px;} +.famfam-email_open_image {background-position: -360px -180px;} +.famfam-emoticon_evilgrin {background-position: -380px -180px;} +.famfam-emoticon_grin {background-position: -400px -180px;} +.famfam-emoticon_happy {background-position: -420px -180px;} +.famfam-emoticon_smile {background-position: -440px -180px;} +.famfam-emoticon_surprised {background-position: -460px -180px;} +.famfam-emoticon_tongue {background-position: -480px -180px;} +.famfam-emoticon_unhappy {background-position: -500px -180px;} +.famfam-emoticon_waii {background-position: -520px -180px;} +.famfam-emoticon_wink {background-position: -540px -180px;} +.famfam-error {background-position: -560px -180px;} +.famfam-error_add {background-position: -580px -180px;} +.famfam-error_delete {background-position: -600px -180px;} +.famfam-error_go {background-position: -620px -180px;} +.famfam-exclamation {background-position: -640px -180px;} +.famfam-eye {background-position: -660px -180px;} +.famfam-feed {background-position: -680px -180px;} +.famfam-feed_add {background-position: -700px -180px;} +.famfam-feed_delete {background-position: -720px -180px;} +.famfam-feed_disk {background-position: -740px -180px;} +.famfam-feed_edit {background-position: -760px -180px;} +.famfam-feed_error {background-position: -780px -180px;} +.famfam-feed_go {background-position: -0px -200px;} +.famfam-feed_key {background-position: -20px -200px;} +.famfam-feed_link {background-position: -40px -200px;} +.famfam-feed_magnify {background-position: -60px -200px;} +.famfam-female {background-position: -80px -200px;} +.famfam-film {background-position: -100px -200px;} +.famfam-film_add {background-position: -120px -200px;} +.famfam-film_delete {background-position: -140px -200px;} +.famfam-film_edit {background-position: -160px -200px;} +.famfam-film_error {background-position: -180px -200px;} +.famfam-film_go {background-position: -200px -200px;} +.famfam-film_key {background-position: -220px -200px;} +.famfam-film_link {background-position: -240px -200px;} +.famfam-film_save {background-position: -260px -200px;} +.famfam-find {background-position: -280px -200px;} +.famfam-flag_blue {background-position: -300px -200px;} +.famfam-flag_green {background-position: -320px -200px;} +.famfam-flag_orange {background-position: -340px -200px;} +.famfam-flag_pink {background-position: -360px -200px;} +.famfam-flag_purple {background-position: -380px -200px;} +.famfam-flag_red {background-position: -400px -200px;} +.famfam-flag_yellow {background-position: -420px -200px;} +.famfam-folder {background-position: -440px -200px;} +.famfam-folder_add {background-position: -460px -200px;} +.famfam-folder_bell {background-position: -480px -200px;} +.famfam-folder_brick {background-position: -500px -200px;} +.famfam-folder_bug {background-position: -520px -200px;} +.famfam-folder_camera {background-position: -540px -200px;} +.famfam-folder_database {background-position: -560px -200px;} +.famfam-folder_delete {background-position: -580px -200px;} +.famfam-folder_edit {background-position: -600px -200px;} +.famfam-folder_error {background-position: -620px -200px;} +.famfam-folder_explore {background-position: -640px -200px;} +.famfam-folder_feed {background-position: -660px -200px;} +.famfam-folder_find {background-position: -680px -200px;} +.famfam-folder_go {background-position: -700px -200px;} +.famfam-folder_heart {background-position: -720px -200px;} +.famfam-folder_image {background-position: -740px -200px;} +.famfam-folder_key {background-position: -760px -200px;} +.famfam-folder_lightbulb {background-position: -780px -200px;} +.famfam-folder_link {background-position: -0px -220px;} +.famfam-folder_magnify {background-position: -20px -220px;} +.famfam-folder_page {background-position: -40px -220px;} +.famfam-folder_page_white {background-position: -60px -220px;} +.famfam-folder_palette {background-position: -80px -220px;} +.famfam-folder_picture {background-position: -100px -220px;} +.famfam-folder_star {background-position: -120px -220px;} +.famfam-folder_table {background-position: -140px -220px;} +.famfam-folder_user {background-position: -160px -220px;} +.famfam-folder_wrench {background-position: -180px -220px;} +.famfam-font {background-position: -200px -220px;} +.famfam-font_add {background-position: -220px -220px;} +.famfam-font_delete {background-position: -240px -220px;} +.famfam-font_go {background-position: -260px -220px;} +.famfam-group {background-position: -280px -220px;} +.famfam-group_add {background-position: -300px -220px;} +.famfam-group_delete {background-position: -320px -220px;} +.famfam-group_edit {background-position: -340px -220px;} +.famfam-group_error {background-position: -360px -220px;} +.famfam-group_gear {background-position: -380px -220px;} +.famfam-group_go {background-position: -400px -220px;} +.famfam-group_key {background-position: -420px -220px;} +.famfam-group_link {background-position: -440px -220px;} +.famfam-heart {background-position: -460px -220px;} +.famfam-heart_add {background-position: -480px -220px;} +.famfam-heart_delete {background-position: -500px -220px;} +.famfam-help {background-position: -520px -220px;} +.famfam-hourglass {background-position: -540px -220px;} +.famfam-hourglass_add {background-position: -560px -220px;} +.famfam-hourglass_delete {background-position: -580px -220px;} +.famfam-hourglass_go {background-position: -600px -220px;} +.famfam-hourglass_link {background-position: -620px -220px;} +.famfam-house {background-position: -640px -220px;} +.famfam-house_go {background-position: -660px -220px;} +.famfam-house_link {background-position: -680px -220px;} +.famfam-html {background-position: -700px -220px;} +.famfam-html_add {background-position: -720px -220px;} +.famfam-html_delete {background-position: -740px -220px;} +.famfam-html_go {background-position: -760px -220px;} +.famfam-html_valid {background-position: -780px -220px;} +.famfam-image {background-position: -0px -240px;} +.famfam-image_add {background-position: -20px -240px;} +.famfam-image_delete {background-position: -40px -240px;} +.famfam-image_edit {background-position: -60px -240px;} +.famfam-image_link {background-position: -80px -240px;} +.famfam-images {background-position: -100px -240px;} +.famfam-information {background-position: -120px -240px;} +.famfam-ipod {background-position: -140px -240px;} +.famfam-ipod_cast {background-position: -160px -240px;} +.famfam-ipod_cast_add {background-position: -180px -240px;} +.famfam-ipod_cast_delete {background-position: -200px -240px;} +.famfam-ipod_sound {background-position: -220px -240px;} +.famfam-joystick {background-position: -240px -240px;} +.famfam-joystick_add {background-position: -260px -240px;} +.famfam-joystick_delete {background-position: -280px -240px;} +.famfam-joystick_error {background-position: -300px -240px;} +.famfam-key {background-position: -320px -240px;} +.famfam-key_add {background-position: -340px -240px;} +.famfam-key_delete {background-position: -360px -240px;} +.famfam-key_go {background-position: -380px -240px;} +.famfam-keyboard {background-position: -400px -240px;} +.famfam-keyboard_add {background-position: -420px -240px;} +.famfam-keyboard_delete {background-position: -440px -240px;} +.famfam-keyboard_magnify {background-position: -460px -240px;} +.famfam-layers {background-position: -480px -240px;} +.famfam-layout {background-position: -500px -240px;} +.famfam-layout_add {background-position: -520px -240px;} +.famfam-layout_content {background-position: -540px -240px;} +.famfam-layout_delete {background-position: -560px -240px;} +.famfam-layout_edit {background-position: -580px -240px;} +.famfam-layout_error {background-position: -600px -240px;} +.famfam-layout_header {background-position: -620px -240px;} +.famfam-layout_link {background-position: -640px -240px;} +.famfam-layout_sidebar {background-position: -660px -240px;} +.famfam-lightbulb {background-position: -680px -240px;} +.famfam-lightbulb_add {background-position: -700px -240px;} +.famfam-lightbulb_delete {background-position: -720px -240px;} +.famfam-lightbulb_off {background-position: -740px -240px;} +.famfam-lightning {background-position: -760px -240px;} +.famfam-lightning_add {background-position: -780px -240px;} +.famfam-lightning_delete {background-position: -0px -260px;} +.famfam-lightning_go {background-position: -20px -260px;} +.famfam-link {background-position: -40px -260px;} +.famfam-link_add {background-position: -60px -260px;} +.famfam-link_break {background-position: -80px -260px;} +.famfam-link_delete {background-position: -100px -260px;} +.famfam-link_edit {background-position: -120px -260px;} +.famfam-link_error {background-position: -140px -260px;} +.famfam-link_go {background-position: -160px -260px;} +.famfam-lock {background-position: -180px -260px;} +.famfam-lock_add {background-position: -200px -260px;} +.famfam-lock_break {background-position: -220px -260px;} +.famfam-lock_delete {background-position: -240px -260px;} +.famfam-lock_edit {background-position: -260px -260px;} +.famfam-lock_go {background-position: -280px -260px;} +.famfam-lock_open {background-position: -300px -260px;} +.famfam-lorry {background-position: -320px -260px;} +.famfam-lorry_add {background-position: -340px -260px;} +.famfam-lorry_delete {background-position: -360px -260px;} +.famfam-lorry_error {background-position: -380px -260px;} +.famfam-lorry_flatbed {background-position: -400px -260px;} +.famfam-lorry_go {background-position: -420px -260px;} +.famfam-lorry_link {background-position: -440px -260px;} +.famfam-magifier_zoom_out {background-position: -460px -260px;} +.famfam-magnifier {background-position: -480px -260px;} +.famfam-magnifier_zoom_in {background-position: -500px -260px;} +.famfam-male {background-position: -520px -260px;} +.famfam-map {background-position: -540px -260px;} +.famfam-map_add {background-position: -560px -260px;} +.famfam-map_delete {background-position: -580px -260px;} +.famfam-map_edit {background-position: -600px -260px;} +.famfam-map_go {background-position: -620px -260px;} +.famfam-map_magnify {background-position: -640px -260px;} +.famfam-medal_bronze_1 {background-position: -660px -260px;} +.famfam-medal_bronze_2 {background-position: -680px -260px;} +.famfam-medal_bronze_3 {background-position: -700px -260px;} +.famfam-medal_bronze_add {background-position: -720px -260px;} +.famfam-medal_bronze_delete {background-position: -740px -260px;} +.famfam-medal_gold_1 {background-position: -760px -260px;} +.famfam-medal_gold_2 {background-position: -780px -260px;} +.famfam-medal_gold_3 {background-position: -0px -280px;} +.famfam-medal_gold_add {background-position: -20px -280px;} +.famfam-medal_gold_delete {background-position: -40px -280px;} +.famfam-medal_silver_1 {background-position: -60px -280px;} +.famfam-medal_silver_2 {background-position: -80px -280px;} +.famfam-medal_silver_3 {background-position: -100px -280px;} +.famfam-medal_silver_add {background-position: -120px -280px;} +.famfam-medal_silver_delete {background-position: -140px -280px;} +.famfam-money {background-position: -160px -280px;} +.famfam-money_add {background-position: -180px -280px;} +.famfam-money_delete {background-position: -200px -280px;} +.famfam-money_dollar {background-position: -220px -280px;} +.famfam-money_euro {background-position: -240px -280px;} +.famfam-money_pound {background-position: -260px -280px;} +.famfam-money_yen {background-position: -280px -280px;} +.famfam-monitor {background-position: -300px -280px;} +.famfam-monitor_add {background-position: -320px -280px;} +.famfam-monitor_delete {background-position: -340px -280px;} +.famfam-monitor_edit {background-position: -360px -280px;} +.famfam-monitor_error {background-position: -380px -280px;} +.famfam-monitor_go {background-position: -400px -280px;} +.famfam-monitor_lightning {background-position: -420px -280px;} +.famfam-monitor_link {background-position: -440px -280px;} +.famfam-mouse {background-position: -460px -280px;} +.famfam-mouse_add {background-position: -480px -280px;} +.famfam-mouse_delete {background-position: -500px -280px;} +.famfam-mouse_error {background-position: -520px -280px;} +.famfam-music {background-position: -540px -280px;} +.famfam-new {background-position: -560px -280px;} +.famfam-newspaper {background-position: -580px -280px;} +.famfam-newspaper_add {background-position: -600px -280px;} +.famfam-newspaper_delete {background-position: -620px -280px;} +.famfam-newspaper_go {background-position: -640px -280px;} +.famfam-newspaper_link {background-position: -660px -280px;} +.famfam-note {background-position: -680px -280px;} +.famfam-note_add {background-position: -700px -280px;} +.famfam-note_delete {background-position: -720px -280px;} +.famfam-note_edit {background-position: -740px -280px;} +.famfam-note_error {background-position: -760px -280px;} +.famfam-note_go {background-position: -780px -280px;} +.famfam-overlays {background-position: -0px -300px;} +.famfam-package {background-position: -20px -300px;} +.famfam-package_add {background-position: -40px -300px;} +.famfam-package_delete {background-position: -60px -300px;} +.famfam-package_go {background-position: -80px -300px;} +.famfam-package_green {background-position: -100px -300px;} +.famfam-package_link {background-position: -120px -300px;} +.famfam-page {background-position: -140px -300px;} +.famfam-page_add {background-position: -160px -300px;} +.famfam-page_attach {background-position: -180px -300px;} +.famfam-page_code {background-position: -200px -300px;} +.famfam-page_copy {background-position: -220px -300px;} +.famfam-page_delete {background-position: -240px -300px;} +.famfam-page_edit {background-position: -260px -300px;} +.famfam-page_error {background-position: -280px -300px;} +.famfam-page_excel {background-position: -300px -300px;} +.famfam-page_find {background-position: -320px -300px;} +.famfam-page_gear {background-position: -340px -300px;} +.famfam-page_go {background-position: -360px -300px;} +.famfam-page_green {background-position: -380px -300px;} +.famfam-page_key {background-position: -400px -300px;} +.famfam-page_lightning {background-position: -420px -300px;} +.famfam-page_link {background-position: -440px -300px;} +.famfam-page_paintbrush {background-position: -460px -300px;} +.famfam-page_paste {background-position: -480px -300px;} +.famfam-page_red {background-position: -500px -300px;} +.famfam-page_refresh {background-position: -520px -300px;} +.famfam-page_save {background-position: -540px -300px;} +.famfam-page_white {background-position: -560px -300px;} +.famfam-page_white_acrobat {background-position: -580px -300px;} +.famfam-page_white_actionscript {background-position: -600px -300px;} +.famfam-page_white_add {background-position: -620px -300px;} +.famfam-page_white_c {background-position: -640px -300px;} +.famfam-page_white_camera {background-position: -660px -300px;} +.famfam-page_white_cd {background-position: -680px -300px;} +.famfam-page_white_code {background-position: -700px -300px;} +.famfam-page_white_code_red {background-position: -720px -300px;} +.famfam-page_white_coldfusion {background-position: -740px -300px;} +.famfam-page_white_compressed {background-position: -760px -300px;} +.famfam-page_white_copy {background-position: -780px -300px;} +.famfam-page_white_cplusplus {background-position: -0px -320px;} +.famfam-page_white_csharp {background-position: -20px -320px;} +.famfam-page_white_cup {background-position: -40px -320px;} +.famfam-page_white_database {background-position: -60px -320px;} +.famfam-page_white_delete {background-position: -80px -320px;} +.famfam-page_white_dvd {background-position: -100px -320px;} +.famfam-page_white_edit {background-position: -120px -320px;} +.famfam-page_white_error {background-position: -140px -320px;} +.famfam-page_white_excel {background-position: -160px -320px;} +.famfam-page_white_find {background-position: -180px -320px;} +.famfam-page_white_flash {background-position: -200px -320px;} +.famfam-page_white_freehand {background-position: -220px -320px;} +.famfam-page_white_gear {background-position: -240px -320px;} +.famfam-page_white_get {background-position: -260px -320px;} +.famfam-page_white_go {background-position: -280px -320px;} +.famfam-page_white_h {background-position: -300px -320px;} +.famfam-page_white_horizontal {background-position: -320px -320px;} +.famfam-page_white_key {background-position: -340px -320px;} +.famfam-page_white_lightning {background-position: -360px -320px;} +.famfam-page_white_link {background-position: -380px -320px;} +.famfam-page_white_magnify {background-position: -400px -320px;} +.famfam-page_white_medal {background-position: -420px -320px;} +.famfam-page_white_office {background-position: -440px -320px;} +.famfam-page_white_paint {background-position: -460px -320px;} +.famfam-page_white_paintbrush {background-position: -480px -320px;} +.famfam-page_white_paste {background-position: -500px -320px;} +.famfam-page_white_php {background-position: -520px -320px;} +.famfam-page_white_picture {background-position: -540px -320px;} +.famfam-page_white_powerpoint {background-position: -560px -320px;} +.famfam-page_white_put {background-position: -580px -320px;} +.famfam-page_white_ruby {background-position: -600px -320px;} +.famfam-page_white_stack {background-position: -620px -320px;} +.famfam-page_white_star {background-position: -640px -320px;} +.famfam-page_white_swoosh {background-position: -660px -320px;} +.famfam-page_white_text {background-position: -680px -320px;} +.famfam-page_white_text_width {background-position: -700px -320px;} +.famfam-page_white_tux {background-position: -720px -320px;} +.famfam-page_white_vector {background-position: -740px -320px;} +.famfam-page_white_visualstudio {background-position: -760px -320px;} +.famfam-page_white_width {background-position: -780px -320px;} +.famfam-page_white_word {background-position: -0px -340px;} +.famfam-page_white_world {background-position: -20px -340px;} +.famfam-page_white_wrench {background-position: -40px -340px;} +.famfam-page_white_zip {background-position: -60px -340px;} +.famfam-page_word {background-position: -80px -340px;} +.famfam-page_world {background-position: -100px -340px;} +.famfam-paintbrush {background-position: -120px -340px;} +.famfam-paintcan {background-position: -140px -340px;} +.famfam-palette {background-position: -160px -340px;} +.famfam-paste_plain {background-position: -180px -340px;} +.famfam-paste_word {background-position: -200px -340px;} +.famfam-pencil {background-position: -220px -340px;} +.famfam-pencil_add {background-position: -240px -340px;} +.famfam-pencil_delete {background-position: -260px -340px;} +.famfam-pencil_go {background-position: -280px -340px;} +.famfam-phone {background-position: -300px -340px;} +.famfam-phone_add {background-position: -320px -340px;} +.famfam-phone_delete {background-position: -340px -340px;} +.famfam-phone_sound {background-position: -360px -340px;} +.famfam-photo {background-position: -380px -340px;} +.famfam-photo_add {background-position: -400px -340px;} +.famfam-photo_delete {background-position: -420px -340px;} +.famfam-photo_link {background-position: -440px -340px;} +.famfam-photos {background-position: -460px -340px;} +.famfam-picture {background-position: -480px -340px;} +.famfam-picture_add {background-position: -500px -340px;} +.famfam-picture_delete {background-position: -520px -340px;} +.famfam-picture_edit {background-position: -540px -340px;} +.famfam-picture_empty {background-position: -560px -340px;} +.famfam-picture_error {background-position: -580px -340px;} +.famfam-picture_go {background-position: -600px -340px;} +.famfam-picture_key {background-position: -620px -340px;} +.famfam-picture_link {background-position: -640px -340px;} +.famfam-picture_save {background-position: -660px -340px;} +.famfam-pictures {background-position: -680px -340px;} +.famfam-pilcrow {background-position: -700px -340px;} +.famfam-pill {background-position: -720px -340px;} +.famfam-pill_add {background-position: -740px -340px;} +.famfam-pill_delete {background-position: -760px -340px;} +.famfam-pill_go {background-position: -780px -340px;} +.famfam-plugin {background-position: -0px -360px;} +.famfam-plugin_add {background-position: -20px -360px;} +.famfam-plugin_delete {background-position: -40px -360px;} +.famfam-plugin_disabled {background-position: -60px -360px;} +.famfam-plugin_edit {background-position: -80px -360px;} +.famfam-plugin_error {background-position: -100px -360px;} +.famfam-plugin_go {background-position: -120px -360px;} +.famfam-plugin_link {background-position: -140px -360px;} +.famfam-printer {background-position: -160px -360px;} +.famfam-printer_add {background-position: -180px -360px;} +.famfam-printer_delete {background-position: -200px -360px;} +.famfam-printer_empty {background-position: -220px -360px;} +.famfam-printer_error {background-position: -240px -360px;} +.famfam-rainbow {background-position: -260px -360px;} +.famfam-report {background-position: -280px -360px;} +.famfam-report_add {background-position: -300px -360px;} +.famfam-report_delete {background-position: -320px -360px;} +.famfam-report_disk {background-position: -340px -360px;} +.famfam-report_edit {background-position: -360px -360px;} +.famfam-report_go {background-position: -380px -360px;} +.famfam-report_key {background-position: -400px -360px;} +.famfam-report_link {background-position: -420px -360px;} +.famfam-report_magnify {background-position: -440px -360px;} +.famfam-report_picture {background-position: -460px -360px;} +.famfam-report_user {background-position: -480px -360px;} +.famfam-report_word {background-position: -500px -360px;} +.famfam-resultset_first {background-position: -520px -360px;} +.famfam-resultset_last {background-position: -540px -360px;} +.famfam-resultset_next {background-position: -560px -360px;} +.famfam-resultset_previous {background-position: -580px -360px;} +.famfam-rosette {background-position: -600px -360px;} +.famfam-rss {background-position: -620px -360px;} +.famfam-rss_add {background-position: -640px -360px;} +.famfam-rss_delete {background-position: -660px -360px;} +.famfam-rss_go {background-position: -680px -360px;} +.famfam-rss_valid {background-position: -700px -360px;} +.famfam-ruby {background-position: -720px -360px;} +.famfam-ruby_add {background-position: -740px -360px;} +.famfam-ruby_delete {background-position: -760px -360px;} +.famfam-ruby_gear {background-position: -780px -360px;} +.famfam-ruby_get {background-position: -0px -380px;} +.famfam-ruby_go {background-position: -20px -380px;} +.famfam-ruby_key {background-position: -40px -380px;} +.famfam-ruby_link {background-position: -60px -380px;} +.famfam-ruby_put {background-position: -80px -380px;} +.famfam-script {background-position: -100px -380px;} +.famfam-script_add {background-position: -120px -380px;} +.famfam-script_code {background-position: -140px -380px;} +.famfam-script_code_red {background-position: -160px -380px;} +.famfam-script_delete {background-position: -180px -380px;} +.famfam-script_edit {background-position: -200px -380px;} +.famfam-script_error {background-position: -220px -380px;} +.famfam-script_gear {background-position: -240px -380px;} +.famfam-script_go {background-position: -260px -380px;} +.famfam-script_key {background-position: -280px -380px;} +.famfam-script_lightning {background-position: -300px -380px;} +.famfam-script_link {background-position: -320px -380px;} +.famfam-script_palette {background-position: -340px -380px;} +.famfam-script_save {background-position: -360px -380px;} +.famfam-server {background-position: -380px -380px;} +.famfam-server_add {background-position: -400px -380px;} +.famfam-server_chart {background-position: -420px -380px;} +.famfam-server_compressed {background-position: -440px -380px;} +.famfam-server_connect {background-position: -460px -380px;} +.famfam-server_database {background-position: -480px -380px;} +.famfam-server_delete {background-position: -500px -380px;} +.famfam-server_edit {background-position: -520px -380px;} +.famfam-server_error {background-position: -540px -380px;} +.famfam-server_go {background-position: -560px -380px;} +.famfam-server_key {background-position: -580px -380px;} +.famfam-server_lightning {background-position: -600px -380px;} +.famfam-server_link {background-position: -620px -380px;} +.famfam-server_uncompressed {background-position: -640px -380px;} +.famfam-shading {background-position: -660px -380px;} +.famfam-shape_align_bottom {background-position: -680px -380px;} +.famfam-shape_align_center {background-position: -700px -380px;} +.famfam-shape_align_left {background-position: -720px -380px;} +.famfam-shape_align_middle {background-position: -740px -380px;} +.famfam-shape_align_right {background-position: -760px -380px;} +.famfam-shape_align_top {background-position: -780px -380px;} +.famfam-shape_flip_horizontal {background-position: -0px -400px;} +.famfam-shape_flip_vertical {background-position: -20px -400px;} +.famfam-shape_group {background-position: -40px -400px;} +.famfam-shape_handles {background-position: -60px -400px;} +.famfam-shape_move_back {background-position: -80px -400px;} +.famfam-shape_move_backwards {background-position: -100px -400px;} +.famfam-shape_move_forwards {background-position: -120px -400px;} +.famfam-shape_move_front {background-position: -140px -400px;} +.famfam-shape_rotate_anticlockwise {background-position: -160px -400px;} +.famfam-shape_rotate_clockwise {background-position: -180px -400px;} +.famfam-shape_square {background-position: -200px -400px;} +.famfam-shape_square_add {background-position: -220px -400px;} +.famfam-shape_square_delete {background-position: -240px -400px;} +.famfam-shape_square_edit {background-position: -260px -400px;} +.famfam-shape_square_error {background-position: -280px -400px;} +.famfam-shape_square_go {background-position: -300px -400px;} +.famfam-shape_square_key {background-position: -320px -400px;} +.famfam-shape_square_link {background-position: -340px -400px;} +.famfam-shape_ungroup {background-position: -360px -400px;} +.famfam-shield {background-position: -380px -400px;} +.famfam-shield_add {background-position: -400px -400px;} +.famfam-shield_delete {background-position: -420px -400px;} +.famfam-shield_go {background-position: -440px -400px;} +.famfam-sitemap {background-position: -460px -400px;} +.famfam-sitemap_color {background-position: -480px -400px;} +.famfam-sound {background-position: -500px -400px;} +.famfam-sound_add {background-position: -520px -400px;} +.famfam-sound_delete {background-position: -540px -400px;} +.famfam-sound_low {background-position: -560px -400px;} +.famfam-sound_mute {background-position: -580px -400px;} +.famfam-sound_none {background-position: -600px -400px;} +.famfam-spellcheck {background-position: -620px -400px;} +.famfam-sport_8ball {background-position: -640px -400px;} +.famfam-sport_basketball {background-position: -660px -400px;} +.famfam-sport_football {background-position: -680px -400px;} +.famfam-sport_golf {background-position: -700px -400px;} +.famfam-sport_raquet {background-position: -720px -400px;} +.famfam-sport_shuttlecock {background-position: -740px -400px;} +.famfam-sport_soccer {background-position: -760px -400px;} +.famfam-sport_tennis {background-position: -780px -400px;} +.famfam-star {background-position: -0px -420px;} +.famfam-status_away {background-position: -20px -420px;} +.famfam-status_busy {background-position: -40px -420px;} +.famfam-status_offline {background-position: -60px -420px;} +.famfam-status_online {background-position: -80px -420px;} +.famfam-stop {background-position: -100px -420px;} +.famfam-style {background-position: -120px -420px;} +.famfam-style_add {background-position: -140px -420px;} +.famfam-style_delete {background-position: -160px -420px;} +.famfam-style_edit {background-position: -180px -420px;} +.famfam-style_go {background-position: -200px -420px;} +.famfam-sum {background-position: -220px -420px;} +.famfam-tab {background-position: -240px -420px;} +.famfam-tab_add {background-position: -260px -420px;} +.famfam-tab_delete {background-position: -280px -420px;} +.famfam-tab_edit {background-position: -300px -420px;} +.famfam-tab_go {background-position: -320px -420px;} +.famfam-table {background-position: -340px -420px;} +.famfam-table_add {background-position: -360px -420px;} +.famfam-table_delete {background-position: -380px -420px;} +.famfam-table_edit {background-position: -400px -420px;} +.famfam-table_error {background-position: -420px -420px;} +.famfam-table_gear {background-position: -440px -420px;} +.famfam-table_go {background-position: -460px -420px;} +.famfam-table_key {background-position: -480px -420px;} +.famfam-table_lightning {background-position: -500px -420px;} +.famfam-table_link {background-position: -520px -420px;} +.famfam-table_multiple {background-position: -540px -420px;} +.famfam-table_refresh {background-position: -560px -420px;} +.famfam-table_relationship {background-position: -580px -420px;} +.famfam-table_row_delete {background-position: -600px -420px;} +.famfam-table_row_insert {background-position: -620px -420px;} +.famfam-table_save {background-position: -640px -420px;} +.famfam-table_sort {background-position: -660px -420px;} +.famfam-tag {background-position: -680px -420px;} +.famfam-tag_blue {background-position: -700px -420px;} +.famfam-tag_blue_add {background-position: -720px -420px;} +.famfam-tag_blue_delete {background-position: -740px -420px;} +.famfam-tag_blue_edit {background-position: -760px -420px;} +.famfam-tag_green {background-position: -780px -420px;} +.famfam-tag_orange {background-position: -0px -440px;} +.famfam-tag_pink {background-position: -20px -440px;} +.famfam-tag_purple {background-position: -40px -440px;} +.famfam-tag_red {background-position: -60px -440px;} +.famfam-tag_yellow {background-position: -80px -440px;} +.famfam-telephone {background-position: -100px -440px;} +.famfam-telephone_add {background-position: -120px -440px;} +.famfam-telephone_delete {background-position: -140px -440px;} +.famfam-telephone_edit {background-position: -160px -440px;} +.famfam-telephone_error {background-position: -180px -440px;} +.famfam-telephone_go {background-position: -200px -440px;} +.famfam-telephone_key {background-position: -220px -440px;} +.famfam-telephone_link {background-position: -240px -440px;} +.famfam-television {background-position: -260px -440px;} +.famfam-television_add {background-position: -280px -440px;} +.famfam-television_delete {background-position: -300px -440px;} +.famfam-text_align_center {background-position: -320px -440px;} +.famfam-text_align_justify {background-position: -340px -440px;} +.famfam-text_align_left {background-position: -360px -440px;} +.famfam-text_align_right {background-position: -380px -440px;} +.famfam-text_allcaps {background-position: -400px -440px;} +.famfam-text_bold {background-position: -420px -440px;} +.famfam-text_columns {background-position: -440px -440px;} +.famfam-text_dropcaps {background-position: -460px -440px;} +.famfam-text_heading_1 {background-position: -480px -440px;} +.famfam-text_heading_2 {background-position: -500px -440px;} +.famfam-text_heading_3 {background-position: -520px -440px;} +.famfam-text_heading_4 {background-position: -540px -440px;} +.famfam-text_heading_5 {background-position: -560px -440px;} +.famfam-text_heading_6 {background-position: -580px -440px;} +.famfam-text_horizontalrule {background-position: -600px -440px;} +.famfam-text_indent {background-position: -620px -440px;} +.famfam-text_indent_remove {background-position: -640px -440px;} +.famfam-text_italic {background-position: -660px -440px;} +.famfam-text_kerning {background-position: -680px -440px;} +.famfam-text_letter_omega {background-position: -700px -440px;} +.famfam-text_letterspacing {background-position: -720px -440px;} +.famfam-text_linespacing {background-position: -740px -440px;} +.famfam-text_list_bullets {background-position: -760px -440px;} +.famfam-text_list_numbers {background-position: -780px -440px;} +.famfam-text_lowercase {background-position: -0px -460px;} +.famfam-text_padding_bottom {background-position: -20px -460px;} +.famfam-text_padding_left {background-position: -40px -460px;} +.famfam-text_padding_right {background-position: -60px -460px;} +.famfam-text_padding_top {background-position: -80px -460px;} +.famfam-text_replace {background-position: -100px -460px;} +.famfam-text_signature {background-position: -120px -460px;} +.famfam-text_smallcaps {background-position: -140px -460px;} +.famfam-text_strikethrough {background-position: -160px -460px;} +.famfam-text_subscript {background-position: -180px -460px;} +.famfam-text_superscript {background-position: -200px -460px;} +.famfam-text_underline {background-position: -220px -460px;} +.famfam-text_uppercase {background-position: -240px -460px;} +.famfam-textfield {background-position: -260px -460px;} +.famfam-textfield_add {background-position: -280px -460px;} +.famfam-textfield_delete {background-position: -300px -460px;} +.famfam-textfield_key {background-position: -320px -460px;} +.famfam-textfield_rename {background-position: -340px -460px;} +.famfam-thumb_down {background-position: -360px -460px;} +.famfam-thumb_up {background-position: -380px -460px;} +.famfam-tick {background-position: -400px -460px;} +.famfam-time {background-position: -420px -460px;} +.famfam-time_add {background-position: -440px -460px;} +.famfam-time_delete {background-position: -460px -460px;} +.famfam-time_go {background-position: -480px -460px;} +.famfam-timeline_marker {background-position: -500px -460px;} +.famfam-transmit {background-position: -520px -460px;} +.famfam-transmit_add {background-position: -540px -460px;} +.famfam-transmit_blue {background-position: -560px -460px;} +.famfam-transmit_delete {background-position: -580px -460px;} +.famfam-transmit_edit {background-position: -600px -460px;} +.famfam-transmit_error {background-position: -620px -460px;} +.famfam-transmit_go {background-position: -640px -460px;} +.famfam-tux {background-position: -660px -460px;} +.famfam-user {background-position: -680px -460px;} +.famfam-user_add {background-position: -700px -460px;} +.famfam-user_comment {background-position: -720px -460px;} +.famfam-user_delete {background-position: -740px -460px;} +.famfam-user_edit {background-position: -760px -460px;} +.famfam-user_female {background-position: -780px -460px;} +.famfam-user_go {background-position: -0px -480px;} +.famfam-user_gray {background-position: -20px -480px;} +.famfam-user_green {background-position: -40px -480px;} +.famfam-user_orange {background-position: -60px -480px;} +.famfam-user_red {background-position: -80px -480px;} +.famfam-user_suit {background-position: -100px -480px;} +.famfam-vcard {background-position: -120px -480px;} +.famfam-vcard_add {background-position: -140px -480px;} +.famfam-vcard_delete {background-position: -160px -480px;} +.famfam-vcard_edit {background-position: -180px -480px;} +.famfam-vector {background-position: -200px -480px;} +.famfam-vector_add {background-position: -220px -480px;} +.famfam-vector_delete {background-position: -240px -480px;} +.famfam-wand {background-position: -260px -480px;} +.famfam-weather_clouds {background-position: -280px -480px;} +.famfam-weather_cloudy {background-position: -300px -480px;} +.famfam-weather_lightning {background-position: -320px -480px;} +.famfam-weather_rain {background-position: -340px -480px;} +.famfam-weather_snow {background-position: -360px -480px;} +.famfam-weather_sun {background-position: -380px -480px;} +.famfam-webcam {background-position: -400px -480px;} +.famfam-webcam_add {background-position: -420px -480px;} +.famfam-webcam_delete {background-position: -440px -480px;} +.famfam-webcam_error {background-position: -460px -480px;} +.famfam-world {background-position: -480px -480px;} +.famfam-world_add {background-position: -500px -480px;} +.famfam-world_delete {background-position: -520px -480px;} +.famfam-world_edit {background-position: -540px -480px;} +.famfam-world_go {background-position: -560px -480px;} +.famfam-world_link {background-position: -580px -480px;} +.famfam-wrench {background-position: -600px -480px;} +.famfam-wrench_orange {background-position: -620px -480px;} +.famfam-xhtml {background-position: -640px -480px;} +.famfam-xhtml_add {background-position: -660px -480px;} +.famfam-xhtml_delete {background-position: -680px -480px;} +.famfam-xhtml_go {background-position: -700px -480px;} +.famfam-xhtml_valid {background-position: -720px -480px;} +.famfam-zoom {background-position: -740px -480px;} +.famfam-zoom_in {background-position: -760px -480px;} +.famfam-zoom_out {background-position: -780px -480px;} diff --git a/site_media/css/override.css b/site_media/css/override.css new file mode 100644 index 0000000000..6aee5182c9 --- /dev/null +++ b/site_media/css/override.css @@ -0,0 +1,12 @@ +.tc { + text-align: center; +} + +#main-navigation ul li a { + line-height: 22px; +} + +.secondary-navigation ul li a { + line-height: 23px; +} + diff --git a/site_media/images/1068504_92921456.jpg b/site_media/images/1068504_92921456.jpg new file mode 100644 index 0000000000..b9cfa7c645 Binary files /dev/null and b/site_media/images/1068504_92921456.jpg differ diff --git a/site_media/images/famfamfam-silk-sprites/famfam-active.png b/site_media/images/famfamfam-silk-sprites/famfam-active.png new file mode 100644 index 0000000000..1589f893f7 Binary files /dev/null and b/site_media/images/famfamfam-silk-sprites/famfam-active.png differ diff --git a/site_media/images/famfamfam-silk-sprites/famfam-hover.png b/site_media/images/famfamfam-silk-sprites/famfam-hover.png new file mode 100644 index 0000000000..250707df76 Binary files /dev/null and b/site_media/images/famfamfam-silk-sprites/famfam-hover.png differ diff --git a/site_media/images/famfamfam-silk-sprites/famfam-inactive.png b/site_media/images/famfamfam-silk-sprites/famfam-inactive.png new file mode 100644 index 0000000000..0ea9c16658 Binary files /dev/null and b/site_media/images/famfamfam-silk-sprites/famfam-inactive.png differ diff --git a/site_media/web_theme_media b/site_media/web_theme_media new file mode 120000 index 0000000000..f69936bc85 --- /dev/null +++ b/site_media/web_theme_media @@ -0,0 +1 @@ +../apps/web_theme/media/ \ No newline at end of file diff --git a/urls.py b/urls.py index 8f52678b5d..62c5aa5aad 100644 --- a/urls.py +++ b/urls.py @@ -1,11 +1,25 @@ from django.conf.urls.defaults import * from django.contrib import admin +from django.conf import settings admin.autodiscover() urlpatterns = patterns('', - # (r'^mayan/', include('mayan.foo.urls')), - + (r'^', include('common.urls')), + (r'^', include('main.urls')), + (r'^documents/', include('documents.urls')), (r'^admin/doc/', include('django.contrib.admindocs.urls')), (r'^admin/', include(admin.site.urls)), ) + +if settings.DEVELOPMENT: + urlpatterns += patterns('', + (r'^%s-site_media/(?P.*)$' % settings.PROJECT_NAME, + 'django.views.static.serve', + {'document_root': 'site_media', 'show_indexes': True}), + ) + + if 'rosetta' in settings.INSTALLED_APPS: + urlpatterns += patterns('', + url(r'^rosetta/', include('rosetta.urls'), name = "rosetta"), + )