From f6355ea108b11f11f859a058e408cb5716e01754 Mon Sep 17 00:00:00 2001 From: Britt Park Date: Mon, 24 Jul 2006 18:27:41 +0000 Subject: [PATCH] Merge from HEAD into WCM-DEV2. Also fixes build breakage in jndi-client and catalina-virtual that I introduced earlier. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3393 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/messages/webclient.properties | 63 +- config/alfresco/web-client-config-dialogs.xml | 40 + .../web-client-config-forum-actions.xml | 43 +- .../alfresco/web-client-config-navigation.xml | 3 - .../alfresco/web-client-config-properties.xml | 77 +- config/alfresco/web-client-config-wizards.xml | 24 + config/alfresco/web-client-config.xml | 61 +- project-build.xml | 1 + .../action/evaluator/ApproveDocEvaluator.java | 3 +- .../ApproveNonDraftDocEvaluator.java | 42 + .../evaluator/CreateForumNodeEvaluator.java | 1 - .../evaluator/DiscussNodeEvaluator.java | 28 +- .../evaluator/DiscussionCutCopyEvaluator.java | 45 + .../action/evaluator/RejectDocEvaluator.java | 3 +- .../evaluator/RejectNonDraftDocEvaluator.java | 42 + .../web/app/AlfrescoNavigationHandler.java | 14 + .../org/alfresco/web/app/Application.java | 11 + .../alfresco/web/app/servlet/BaseServlet.java | 23 +- .../web/app/servlet/CommandServlet.java | 2 +- .../app/servlet/TemplateContentServlet.java | 3 +- .../web/app/servlet/ajax/AjaxCommand.java | 37 + .../web/app/servlet/ajax/AjaxServlet.java | 184 + .../web/app/servlet/ajax/BaseAjaxCommand.java | 19 + .../web/app/servlet/ajax/GetCommand.java | 69 + .../web/app/servlet/ajax/InvokeCommand.java | 97 + .../web/bean/AdminNodeBrowseBean.java | 2 +- .../alfresco/web/bean/AdvancedSearchBean.java | 6 +- .../org/alfresco/web/bean/BrowseBean.java | 121 +- .../web/bean/CheckinCheckoutBean.java | 77 +- .../org/alfresco/web/bean/ExportBean.java | 2 +- .../org/alfresco/web/bean/GroupsBean.java | 20 +- .../alfresco/web/bean/LinkPropertiesBean.java | 2 +- .../org/alfresco/web/bean/NavigationBean.java | 56 +- .../org/alfresco/web/bean/SearchContext.java | 6 +- .../alfresco/web/bean/SpaceDetailsBean.java | 244 +- .../org/alfresco/web/bean/TrashcanBean.java | 19 + .../alfresco/web/bean/UserShortcutsBean.java | 33 +- .../org/alfresco/web/bean/WorkflowUtil.java | 2 +- .../web/bean/actions/BaseActionWizard.java | 40 +- .../web/bean/actions/RunActionWizard.java | 40 +- .../bean/actions/handlers/CheckInHandler.java | 2 +- .../alfresco/web/bean/ajax/NodeInfoBean.java | 128 + .../web/bean/clipboard/ClipboardBean.java | 7 + .../web/bean/content/AddContentDialog.java | 45 +- .../web/bean/content/DeleteContentDialog.java | 87 + .../web/bean/dashboard/DashboardManager.java | 404 ++ .../web/bean/dashboard/DashboardWizard.java | 467 ++ .../web/bean/dashboard/PageConfig.java | 381 ++ .../bean/forums/CreateDiscussionDialog.java | 13 +- .../web/bean/forums/CreateReplyDialog.java | 30 - .../web/bean/forums/DeleteForumDialog.java | 103 + .../web/bean/forums/DeleteForumsDialog.java | 70 + .../web/bean/forums/DeletePostDialog.java | 44 + .../web/bean/forums/DeleteTopicDialog.java | 89 + .../alfresco/web/bean/forums/ForumsBean.java | 252 +- .../web/bean/repository/DataDictionary.java | 5 - .../alfresco/web/bean/repository/Node.java | 2 +- .../web/bean/repository/Preferences.java | 99 + .../bean/repository/PreferencesService.java | 63 + .../alfresco/web/bean/repository/User.java | 110 +- .../alfresco/web/bean/rules/RulesBean.java | 2 +- .../web/bean/spaces/CreateSpaceWizard.java | 30 +- .../web/bean/spaces/DeleteSpaceDialog.java | 100 + .../alfresco/web/bean/users/UsersBean.java | 72 +- .../web/bean/wizard/BaseWizardBean.java | 10 + .../alfresco/web/bean/wizard/IWizardBean.java | 14 + .../web/bean/wizard/InviteUsersWizard.java | 2 +- .../web/bean/wizard/WizardManager.java | 8 +- .../web/config/ActionsConfigElement.java | 2 +- .../alfresco/web/config/AspectEvaluator.java | 3 +- .../web/config/ClientConfigElement.java | 19 + .../web/config/ClientElementReader.java | 8 + .../web/config/DashboardsConfigElement.java | 152 + .../web/config/DashboardsElementReader.java | 205 + source/java/org/alfresco/web/data/Sort.java | 18 +- .../org/alfresco/web/ui/common/Utils.java | 35 + .../ui/common/component/UIImagePicker.java | 5 - .../ui/common/component/data/UISortLink.java | 2 +- .../description/UIDynamicDescription.java | 5 +- .../component/evaluator/BaseEvaluator.java | 2 +- .../web/ui/common/tag/ActionLinkTag.java | 11 +- .../web/ui/repo/component/UINodeInfo.java | 137 + .../component/property/UIPropertySheet.java | 57 +- .../template/DefaultModelHelper.java | 10 +- .../repo/component/template/UITemplate.java | 24 +- .../renderer/NodeDescendantsLinkRenderer.java | 1 - .../alfresco/web/ui/repo/tag/NodeInfoTag.java | 77 + source/web/WEB-INF/alfresco.tld | 6 + source/web/WEB-INF/faces-config-beans.xml | 269 + .../web/WEB-INF/faces-config-enterprise.xml | 24 + .../web/WEB-INF/faces-config-navigation.xml | 128 +- source/web/WEB-INF/faces-config-repo.xml | 5 + source/web/WEB-INF/repo.tld | 24 + source/web/WEB-INF/web.xml | 12 +- source/web/css/main.css | 31 + source/web/images/filetypes/odf.gif | Bin 0 -> 1019 bytes source/web/images/filetypes/odg.gif | Bin 0 -> 1021 bytes source/web/images/filetypes/odp.gif | Bin 0 -> 1030 bytes source/web/images/filetypes/ods.gif | Bin 0 -> 1026 bytes source/web/images/filetypes/odt.gif | Bin 1024 -> 1010 bytes source/web/images/filetypes32/odf.gif | Bin 0 -> 1574 bytes source/web/images/filetypes32/odg.gif | Bin 0 -> 1590 bytes source/web/images/filetypes32/odp.gif | Bin 0 -> 1611 bytes source/web/images/filetypes32/ods.gif | Bin 0 -> 1590 bytes source/web/images/filetypes32/odt.gif | Bin 1576 -> 1501 bytes source/web/images/icons/configure.gif | Bin 0 -> 1008 bytes .../web/images/icons/configure_dashboard.gif | Bin 0 -> 998 bytes .../icons/configure_dashboard_large.gif | Bin 0 -> 1488 bytes source/web/images/icons/dashboard.gif | Bin 0 -> 998 bytes source/web/images/icons/dashboard_large.gif | Bin 0 -> 1488 bytes .../icons/layout_narrow_left_2column.gif | Bin 0 -> 840 bytes .../icons/layout_narrow_right_2column.gif | Bin 0 -> 841 bytes .../web/images/icons/layout_single_column.gif | Bin 0 -> 807 bytes .../web/images/icons/layout_three_column.gif | Bin 0 -> 866 bytes source/web/images/icons/user_console.gif | Bin 0 -> 1042 bytes .../web/images/icons/user_console_large.gif | Bin 0 -> 1558 bytes source/web/images/logo/jooreports.png | Bin 0 -> 6375 bytes source/web/jsp/admin/admin-console.jsp | 12 +- source/web/jsp/browse/browse.jsp | 13 +- source/web/jsp/categories/categories.jsp | 2 +- source/web/jsp/dashboard.jsp | 169 - .../container.jsp} | 283 +- .../jsp/dashboards/dashlets/calculator.jsp | 22 + .../jsp/dashboards/dashlets/calculator.png | Bin 0 -> 1920 bytes .../web/jsp/dashboards/dashlets/calendar.jsp | 22 + .../web/jsp/dashboards/dashlets/calendar.png | Bin 0 -> 7239 bytes .../dashlets/content-checkedout.jsp | 22 + .../dashlets/content-checkedout.png | Bin 0 -> 28296 bytes .../dashboards/dashlets/getting-started.jsp | 57 + .../dashlets/my-completed-tasks.png | Bin 0 -> 15407 bytes .../web/jsp/dashboards/dashlets/my-docs.jsp | 22 + .../jsp/dashboards/dashlets/my-tasks-todo.png | Bin 0 -> 15216 bytes .../dashlets/tasklist-completed.jsp | 22 + .../jsp/dashboards/dashlets/tasklist-todo.jsp | 22 + source/web/jsp/dashboards/dummy.jsp | 16 + .../layouts/narrow-left-2column.jsp | 84 + .../layouts/narrow-right-2column.jsp | 84 + .../jsp/dashboards/layouts/single-column.jsp | 56 + .../jsp/dashboards/layouts/three-column.jsp | 113 + source/web/jsp/dashboards/wizard/columns.jsp | 76 + source/web/jsp/dashboards/wizard/layout.jsp | 56 + source/web/jsp/dialog/about.jsp | 3 + source/web/jsp/dialog/delete-space.jsp | 173 - source/web/jsp/dialog/delete.jsp | 26 + .../edit-space-category.jsp} | 343 +- source/web/jsp/dialog/export.jsp | 2 +- source/web/jsp/dialog/import.jsp | 2 +- source/web/jsp/dialog/space-details.jsp | 29 + source/web/jsp/dialog/system-info.jsp | 2 +- source/web/jsp/forums/create-reply-dialog.jsp | 29 +- source/web/jsp/forums/delete-forum.jsp | 173 - source/web/jsp/forums/delete-post.jsp | 173 - source/web/jsp/forums/delete-topic.jsp | 173 - source/web/jsp/groups/groups.jsp | 2 +- source/web/jsp/parts/titlebar.jsp | 22 +- .../change-my-password.jsp} | 380 +- source/web/jsp/users/change-password.jsp | 2 +- source/web/jsp/users/delete-user.jsp | 2 +- .../user-console.jsp} | 121 +- source/web/jsp/users/users.jsp | 6 +- .../web/jsp/wizard/add-content/properties.jsp | 267 - source/web/jsp/wizard/add-content/summary.jsp | 173 - source/web/jsp/wizard/add-content/upload.jsp | 212 - source/web/jsp/wizard/container.jsp | 2 +- .../jsp/wizard/create-content/create-html.jsp | 208 - .../jsp/wizard/create-content/properties.jsp | 251 - .../jsp/wizard/create-content/select-type.jsp | 191 - source/web/jsp/wizard/summary.jsp | 6 +- source/web/scripts/ajax/common.js | 22 + source/web/scripts/ajax/dojo.js | 5593 +++++++++++++++++ source/web/scripts/ajax/node-info.js | 73 + 171 files changed, 11880 insertions(+), 3450 deletions(-) create mode 100644 source/java/org/alfresco/web/action/evaluator/ApproveNonDraftDocEvaluator.java create mode 100644 source/java/org/alfresco/web/action/evaluator/DiscussionCutCopyEvaluator.java create mode 100644 source/java/org/alfresco/web/action/evaluator/RejectNonDraftDocEvaluator.java create mode 100644 source/java/org/alfresco/web/app/servlet/ajax/AjaxCommand.java create mode 100644 source/java/org/alfresco/web/app/servlet/ajax/AjaxServlet.java create mode 100644 source/java/org/alfresco/web/app/servlet/ajax/BaseAjaxCommand.java create mode 100644 source/java/org/alfresco/web/app/servlet/ajax/GetCommand.java create mode 100644 source/java/org/alfresco/web/app/servlet/ajax/InvokeCommand.java create mode 100644 source/java/org/alfresco/web/bean/ajax/NodeInfoBean.java create mode 100644 source/java/org/alfresco/web/bean/content/DeleteContentDialog.java create mode 100644 source/java/org/alfresco/web/bean/dashboard/DashboardManager.java create mode 100644 source/java/org/alfresco/web/bean/dashboard/DashboardWizard.java create mode 100644 source/java/org/alfresco/web/bean/dashboard/PageConfig.java create mode 100644 source/java/org/alfresco/web/bean/forums/DeleteForumDialog.java create mode 100644 source/java/org/alfresco/web/bean/forums/DeleteForumsDialog.java create mode 100644 source/java/org/alfresco/web/bean/forums/DeletePostDialog.java create mode 100644 source/java/org/alfresco/web/bean/forums/DeleteTopicDialog.java create mode 100644 source/java/org/alfresco/web/bean/repository/Preferences.java create mode 100644 source/java/org/alfresco/web/bean/repository/PreferencesService.java create mode 100644 source/java/org/alfresco/web/bean/spaces/DeleteSpaceDialog.java create mode 100644 source/java/org/alfresco/web/config/DashboardsConfigElement.java create mode 100644 source/java/org/alfresco/web/config/DashboardsElementReader.java create mode 100644 source/java/org/alfresco/web/ui/repo/component/UINodeInfo.java create mode 100644 source/java/org/alfresco/web/ui/repo/tag/NodeInfoTag.java create mode 100644 source/web/WEB-INF/faces-config-enterprise.xml create mode 100644 source/web/images/filetypes/odf.gif create mode 100644 source/web/images/filetypes/odg.gif create mode 100644 source/web/images/filetypes/odp.gif create mode 100644 source/web/images/filetypes/ods.gif create mode 100644 source/web/images/filetypes32/odf.gif create mode 100644 source/web/images/filetypes32/odg.gif create mode 100644 source/web/images/filetypes32/odp.gif create mode 100644 source/web/images/filetypes32/ods.gif create mode 100644 source/web/images/icons/configure.gif create mode 100644 source/web/images/icons/configure_dashboard.gif create mode 100644 source/web/images/icons/configure_dashboard_large.gif create mode 100644 source/web/images/icons/dashboard.gif create mode 100644 source/web/images/icons/dashboard_large.gif create mode 100644 source/web/images/icons/layout_narrow_left_2column.gif create mode 100644 source/web/images/icons/layout_narrow_right_2column.gif create mode 100644 source/web/images/icons/layout_single_column.gif create mode 100644 source/web/images/icons/layout_three_column.gif create mode 100644 source/web/images/icons/user_console.gif create mode 100644 source/web/images/icons/user_console_large.gif create mode 100644 source/web/images/logo/jooreports.png delete mode 100644 source/web/jsp/dashboard.jsp rename source/web/jsp/{dialog/delete-file.jsp => dashboards/container.jsp} (60%) create mode 100644 source/web/jsp/dashboards/dashlets/calculator.jsp create mode 100644 source/web/jsp/dashboards/dashlets/calculator.png create mode 100644 source/web/jsp/dashboards/dashlets/calendar.jsp create mode 100644 source/web/jsp/dashboards/dashlets/calendar.png create mode 100644 source/web/jsp/dashboards/dashlets/content-checkedout.jsp create mode 100644 source/web/jsp/dashboards/dashlets/content-checkedout.png create mode 100644 source/web/jsp/dashboards/dashlets/getting-started.jsp create mode 100644 source/web/jsp/dashboards/dashlets/my-completed-tasks.png create mode 100644 source/web/jsp/dashboards/dashlets/my-docs.jsp create mode 100644 source/web/jsp/dashboards/dashlets/my-tasks-todo.png create mode 100644 source/web/jsp/dashboards/dashlets/tasklist-completed.jsp create mode 100644 source/web/jsp/dashboards/dashlets/tasklist-todo.jsp create mode 100644 source/web/jsp/dashboards/dummy.jsp create mode 100644 source/web/jsp/dashboards/layouts/narrow-left-2column.jsp create mode 100644 source/web/jsp/dashboards/layouts/narrow-right-2column.jsp create mode 100644 source/web/jsp/dashboards/layouts/single-column.jsp create mode 100644 source/web/jsp/dashboards/layouts/three-column.jsp create mode 100644 source/web/jsp/dashboards/wizard/columns.jsp create mode 100644 source/web/jsp/dashboards/wizard/layout.jsp delete mode 100644 source/web/jsp/dialog/delete-space.jsp create mode 100644 source/web/jsp/dialog/delete.jsp rename source/web/jsp/{wizard/create-content/create-text.jsp => dialog/edit-space-category.jsp} (70%) delete mode 100644 source/web/jsp/forums/delete-forum.jsp delete mode 100644 source/web/jsp/forums/delete-post.jsp delete mode 100644 source/web/jsp/forums/delete-topic.jsp rename source/web/jsp/{wizard/create-content/summary.jsp => users/change-my-password.jsp} (65%) rename source/web/jsp/{forums/delete-forums.jsp => users/user-console.jsp} (53%) delete mode 100644 source/web/jsp/wizard/add-content/properties.jsp delete mode 100644 source/web/jsp/wizard/add-content/summary.jsp delete mode 100644 source/web/jsp/wizard/add-content/upload.jsp delete mode 100644 source/web/jsp/wizard/create-content/create-html.jsp delete mode 100644 source/web/jsp/wizard/create-content/properties.jsp delete mode 100644 source/web/jsp/wizard/create-content/select-type.jsp create mode 100644 source/web/scripts/ajax/common.js create mode 100644 source/web/scripts/ajax/dojo.js create mode 100644 source/web/scripts/ajax/node-info.js diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index d300015928..4371b70c0a 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -29,6 +29,7 @@ modify_content_user_roles_description=Modify the permissions granted to a user f advancedsearch_description=Perform a more detailed search of the repository. edit_content_description=Modify the content properties then click OK. editcategory_description=Set the category for the document then click OK. +editcategory_space_description=Set the category for the space then click OK. editworkflow_description=Modify the simple workflow properties then click OK. editspace_description=Modify the space properties then click OK. editlink_description=Modify the link object properties then click OK. @@ -86,6 +87,8 @@ change=Change set=Set no_categories_applied=This document does not yet have any categories applied. has_following_categories=This document has the following categories applied... +no_categories_applied_space=This space does not yet have any categories applied. +has_following_categories_space=This space has the following categories applied... moved=moved copied=copied document_action=The document will be {0} to ''{1}'' if the ''{2}'' action is taken. @@ -511,6 +514,7 @@ not_inline_editable=This document is not inline editable. allow_inline_editing=Allow Inline Editing not_in_workflow=This document is not part of any workflow. not_in_category=This document is not categorized. +not_in_category_space=This space is not categorized. not_versioned=This document has no version history. allow_categorization=Allow Categorization allow_versioning=Allow Versioning @@ -817,11 +821,11 @@ recover_listed_items=Recover Listed Items recover_listed_items_info=Recover the listed files and spaces from the deleted file store recover_listed_items_confirm=Are you sure you want to recover the following deleted files and spaces from the deleted file store? recovered_item_success=The item \"{0}\" has been successfully recovered. -recovered_item_parent=Failed to recover the item \"{0}\" as the original parent folder is missing, please select a new folder destination. +recovered_item_parent=Failed to recover the item \"{0}\" as the parent folder is missing, please select a new folder destination. recovered_item_parent_short=Parent folder missing -recovered_item_permission=Failed to recover the item \"{0}\" as you do not have the appropriate permissions to restore the item to the original parent folder, please select a new folder destination. +recovered_item_permission=Failed to recover the item \"{0}\" as you do not have the appropriate permissions to restore the item to the parent folder, please select a new folder destination. recovered_item_permission_short=No permissions to write -recovered_item_integrity=Failed to recover the item \"{0}\" as there is now an item in the original parent folder with the same name, please select a new folder destination. +recovered_item_integrity=Failed to recover the item \"{0}\" as there is now an item in the parent folder with the same name, please select a new folder destination. recovered_item_integrity_short=Item with same name exists recovered_item_failure=Failed to recover the item \"{0}\" due to error: {1} recovered_item_failure_short=Failed @@ -843,6 +847,58 @@ recovery_report_success=The following items were recovered successfully recovery_report_failed=The following items failed to recover recovery_report_reason=Failure Reason +# My Alfresco messages +my_alfresco=My Alfresco +title_my_alfresco=My Alfresco +dashboard_info=My Alfresco Dashboard +dashboard_description=Configure this view and build your personal Alfresco dashboard +configure=Configure + +# My Alfresco Layout Manager wizard messages +configure_dashboard_title=Configure Dashboard Wizard +configure_dashboard_desc=This wizard helps you configure your dashboard layout and contents +step_layout=Layout +configure_dashboard_step1_title=Step One - Select Layout +configure_dashboard_step1_desc=Choose the layout and number of columns for your dashboard. +step_columns=Components +configure_dashboard_step2_title=Step Two - Select Components +configure_dashboard_step2_desc=Select the components for your dashboard and add them to the columns. +configure_dashboard_finish_instruction=To save the dashboard configuration click Finish. To review or change your selections click Back. +select_layout=Select the style of layout for your dashboard. Changing your existing dashboard layout to another with less columns will result in the additional columns being removed. +select_column=Select the column to configure +dashlet_list=Available Components +dashlet_btn_select=Add +dashlet_btn_remove=Remove +selected_dashlets=Selected Components +dashboard_column=Column +column_max_components=this column can display {0} components + +# My Alfresco Layouts messages +layout_single_label=Single Column +layout_single_desc=This layout displays components in a single column the full width of the page +layout_narrow_left_label=Two Column Narrow Left +layout_narrow_left_desc=This layout display components in two columns with a narrow left hand column +layout_narrow_right_label=Two Column Narrow Right +layout_narrow_right_desc=This layout display components in two columns with a narrow right hand column +layout_three_column_label=Three Column +layout_three_column_desc=This layout displays components across three columns of equal width + +# My Alfresco Dashlet components messages +dashlet_gettingstarted_label=Getting Started +dashlet_gettingstarted_desc=Displays helpful information for getting started with the Alfresco web-client + +# User Console and Settings messages +title_user_console=User Options +user_console=User Options +user_console_info=User Options +user_console_description=Use this page to change your options and settings +my_details=My Details +general_pref=General Preferences +change_my_password_description=Use this view to change your password +change_my_password_instructions=Enter your new password. +old_password=Old Password +new_password=New Password + # Admin Console messages title_admin_console=Administration Console admin_console=Administration Console @@ -984,6 +1040,7 @@ error_update_simpleworkflow=Failed to update simple workflow due to system error error_workflow_approve=Failed to approve the document due to system error: {0} error_workflow_reject=Failed to reject the document due to system error: {0} error_aspect_classify=Failed to apply the ''classifiable'' aspect to the document due to system error: {0} +error_aspect_classify_space=Failed to apply the ''classifiable'' aspect to the space due to system error: {0} error_aspect_versioning=Failed to apply the ''versionable'' aspect to the document due to system error: {0} error_aspect_inlineeditable=Failed to apply the ''inlineeditable'' aspect to the document due to system error: {0} error_content_missing=The node''s content is missing: \n node: {0} \n reader: {1} \nPlease contact your system administrator. diff --git a/config/alfresco/web-client-config-dialogs.xml b/config/alfresco/web-client-config-dialogs.xml index 935a75351d..fa5eea4ae6 100644 --- a/config/alfresco/web-client-config-dialogs.xml +++ b/config/alfresco/web-client-config-dialogs.xml @@ -15,6 +15,11 @@ icon="/images/icons/details_large.gif" title-id="modify_space_properties" description-id="editspace_description" /> + + + + + @@ -72,4 +81,35 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/alfresco/web-client-config-forum-actions.xml b/config/alfresco/web-client-config-forum-actions.xml index 6ce65784fd..8037d12083 100644 --- a/config/alfresco/web-client-config-forum-actions.xml +++ b/config/alfresco/web-client-config-forum-actions.xml @@ -16,6 +16,35 @@ #{actionContext.id} + + + + + org.alfresco.web.action.evaluator.DiscussionCutCopyEvaluator + + Delete + + cut + /images/icons/cut.gif + #{ClipboardBean.cutNode} + + #{actionContext.id} + + + + + + + + org.alfresco.web.action.evaluator.DiscussionCutCopyEvaluator + copy + /images/icons/copy.gif + #{ClipboardBean.copyNode} + + #{actionContext.id} + + + @@ -70,8 +99,8 @@ delete_forums /images/icons/delete_forums.gif - dialog:deleteForums - #{BrowseBean.setupContentAction} + dialog:deleteSpace + #{BrowseBean.setupDeleteAction} #{actionContext.id} @@ -84,8 +113,8 @@ delete_forum /images/icons/delete_forum.gif - dialog:deleteForum - #{BrowseBean.setupContentAction} + dialog:deleteSpace + #{BrowseBean.setupDeleteAction} #{actionContext.id} @@ -108,8 +137,8 @@ delete_topic /images/icons/delete_topic.gif - dialog:deleteTopic - #{BrowseBean.setupContentAction} + dialog:deleteSpace + #{BrowseBean.setupDeleteAction} #{actionContext.id} @@ -160,7 +189,7 @@ delete_post /images/icons/delete.gif - dialog:deletePost + dialog:deleteFile #{BrowseBean.setupContentAction} #{actionContext.id} diff --git a/config/alfresco/web-client-config-navigation.xml b/config/alfresco/web-client-config-navigation.xml index c340a99c71..0dab5a7ec2 100644 --- a/config/alfresco/web-client-config-navigation.xml +++ b/config/alfresco/web-client-config-navigation.xml @@ -5,7 +5,6 @@ - @@ -14,7 +13,6 @@ - @@ -23,7 +21,6 @@ - diff --git a/config/alfresco/web-client-config-properties.xml b/config/alfresco/web-client-config-properties.xml index e7afc96f0f..00cd3f2ffb 100644 --- a/config/alfresco/web-client-config-properties.xml +++ b/config/alfresco/web-client-config-properties.xml @@ -35,32 +35,6 @@ ignore-if-missing="false" /> - - - - - - - - - - - - - - - - - - - - - - - @@ -97,7 +71,7 @@ - + @@ -105,6 +79,20 @@ + + + + + + + + + + + + + @@ -184,4 +172,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/alfresco/web-client-config-wizards.xml b/config/alfresco/web-client-config-wizards.xml index 638d499e6b..a3aad002c2 100644 --- a/config/alfresco/web-client-config-wizards.xml +++ b/config/alfresco/web-client-config-wizards.xml @@ -158,6 +158,30 @@ + + + + + + + + + + + + + diff --git a/config/alfresco/web-client-config.xml b/config/alfresco/web-client-config.xml index 552561aba3..5c5b6cb4da 100644 --- a/config/alfresco/web-client-config.xml +++ b/config/alfresco/web-client-config.xml @@ -16,6 +16,7 @@ + @@ -42,9 +43,8 @@ false - - -1 - + + -1 @@ -130,9 +130,9 @@ - + - + @@ -160,7 +160,48 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -204,9 +245,14 @@ + + + + + @@ -214,6 +260,9 @@ + + + diff --git a/project-build.xml b/project-build.xml index 9f216bcb98..23ad4472ec 100644 --- a/project-build.xml +++ b/project-build.xml @@ -40,6 +40,7 @@ + diff --git a/source/java/org/alfresco/web/action/evaluator/ApproveDocEvaluator.java b/source/java/org/alfresco/web/action/evaluator/ApproveDocEvaluator.java index 5f4ea1ebb9..714c35f4f5 100644 --- a/source/java/org/alfresco/web/action/evaluator/ApproveDocEvaluator.java +++ b/source/java/org/alfresco/web/action/evaluator/ApproveDocEvaluator.java @@ -34,8 +34,7 @@ public final class ApproveDocEvaluator implements ActionEvaluator public boolean evaluate(Node node) { return (node.getProperties().get("app:approveStep") != null && - node.isLocked() == false && - node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false); + node.isLocked() == false); } } /* diff --git a/source/java/org/alfresco/web/action/evaluator/ApproveNonDraftDocEvaluator.java b/source/java/org/alfresco/web/action/evaluator/ApproveNonDraftDocEvaluator.java new file mode 100644 index 0000000000..01ba1aed31 --- /dev/null +++ b/source/java/org/alfresco/web/action/evaluator/ApproveNonDraftDocEvaluator.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.web.action.evaluator; + +import org.alfresco.model.ContentModel; +import org.alfresco.web.action.ActionEvaluator; +import org.alfresco.web.bean.repository.Node; + +/** + * UI Action Evaluator - 'Approve' workflow step for document. + * + * @author Kevin Roast + */ +public final class ApproveNonDraftDocEvaluator implements ActionEvaluator +{ + /** + * @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node) + */ + public boolean evaluate(Node node) + { + return (node.getProperties().get("app:approveStep") != null && + node.isLocked() == false && + node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false); + } +} +/* + +*/ \ No newline at end of file diff --git a/source/java/org/alfresco/web/action/evaluator/CreateForumNodeEvaluator.java b/source/java/org/alfresco/web/action/evaluator/CreateForumNodeEvaluator.java index cda684ec76..135de5addf 100644 --- a/source/java/org/alfresco/web/action/evaluator/CreateForumNodeEvaluator.java +++ b/source/java/org/alfresco/web/action/evaluator/CreateForumNodeEvaluator.java @@ -16,7 +16,6 @@ */ package org.alfresco.web.action.evaluator; -import org.alfresco.model.ContentModel; import org.alfresco.model.ForumModel; import org.alfresco.web.action.ActionEvaluator; import org.alfresco.web.bean.repository.Node; diff --git a/source/java/org/alfresco/web/action/evaluator/DiscussNodeEvaluator.java b/source/java/org/alfresco/web/action/evaluator/DiscussNodeEvaluator.java index 47183fa100..062d279cd9 100644 --- a/source/java/org/alfresco/web/action/evaluator/DiscussNodeEvaluator.java +++ b/source/java/org/alfresco/web/action/evaluator/DiscussNodeEvaluator.java @@ -16,10 +16,17 @@ */ package org.alfresco.web.action.evaluator; -import org.alfresco.model.ContentModel; +import java.util.List; + +import javax.faces.context.FacesContext; + import org.alfresco.model.ForumModel; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.web.action.ActionEvaluator; import org.alfresco.web.bean.repository.Node; +import org.alfresco.web.bean.repository.Repository; /** * UI Action Evaluator - Discuss a node. @@ -33,7 +40,24 @@ public final class DiscussNodeEvaluator implements ActionEvaluator */ public boolean evaluate(Node node) { - return (node.hasAspect(ForumModel.ASPECT_DISCUSSABLE) == true); + boolean result = false; + + if (node.hasAspect(ForumModel.ASPECT_DISCUSSABLE)) + { + NodeService nodeService = Repository.getServiceRegistry( + FacesContext.getCurrentInstance()).getNodeService(); + List children = nodeService.getChildAssocs( + node.getNodeRef(), ForumModel.ASSOC_DISCUSSION, + RegexQNamePattern.MATCH_ALL); + + // make sure there is one visible child association for the node + if (children.size() == 1) + { + result = true; + } + } + + return result; } } /* diff --git a/source/java/org/alfresco/web/action/evaluator/DiscussionCutCopyEvaluator.java b/source/java/org/alfresco/web/action/evaluator/DiscussionCutCopyEvaluator.java new file mode 100644 index 0000000000..96922b2d77 --- /dev/null +++ b/source/java/org/alfresco/web/action/evaluator/DiscussionCutCopyEvaluator.java @@ -0,0 +1,45 @@ +package org.alfresco.web.action.evaluator; + +import javax.faces.context.FacesContext; + +import org.alfresco.model.ForumModel; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; +import org.alfresco.web.action.ActionEvaluator; +import org.alfresco.web.bean.repository.Node; +import org.alfresco.web.bean.repository.Repository; + +/** + * Evaluates whether the cut or copy action should be visible. + * + * If the node is a discussion don't allow the action. + * + * @author gavinc + */ +public class DiscussionCutCopyEvaluator implements ActionEvaluator +{ + /** + * @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node) + */ + public boolean evaluate(Node node) + { + boolean result = true; + + // if the node in question is a forum... + if (node.getType().equals(ForumModel.TYPE_FORUM)) + { + // get the association type + FacesContext context = FacesContext.getCurrentInstance(); + NodeService nodeService = Repository.getServiceRegistry(context).getNodeService(); + + ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(node.getNodeRef()); + QName assocType = parentAssoc.getTypeQName(); + + // only allow the action if the association type is not the discussion assoc + result = (assocType.equals(ForumModel.ASSOC_DISCUSSION) == false); + } + + return result; + } +} diff --git a/source/java/org/alfresco/web/action/evaluator/RejectDocEvaluator.java b/source/java/org/alfresco/web/action/evaluator/RejectDocEvaluator.java index 9ad88edcf7..68a7e3df14 100644 --- a/source/java/org/alfresco/web/action/evaluator/RejectDocEvaluator.java +++ b/source/java/org/alfresco/web/action/evaluator/RejectDocEvaluator.java @@ -34,8 +34,7 @@ public final class RejectDocEvaluator implements ActionEvaluator public boolean evaluate(Node node) { return (node.getProperties().get("app:rejectStep") != null && - node.isLocked() == false && - node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false); + node.isLocked() == false); } } /* diff --git a/source/java/org/alfresco/web/action/evaluator/RejectNonDraftDocEvaluator.java b/source/java/org/alfresco/web/action/evaluator/RejectNonDraftDocEvaluator.java new file mode 100644 index 0000000000..29eb1a64a1 --- /dev/null +++ b/source/java/org/alfresco/web/action/evaluator/RejectNonDraftDocEvaluator.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.web.action.evaluator; + +import org.alfresco.model.ContentModel; +import org.alfresco.web.action.ActionEvaluator; +import org.alfresco.web.bean.repository.Node; + +/** + * UI Action Evaluator - 'Reject' workflow step for document. + * + * @author Kevin Roast + */ +public final class RejectNonDraftDocEvaluator implements ActionEvaluator +{ + /** + * @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node) + */ + public boolean evaluate(Node node) + { + return (node.getProperties().get("app:rejectStep") != null && + node.isLocked() == false && + node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false); + } +} +/* + +*/ \ No newline at end of file diff --git a/source/java/org/alfresco/web/app/AlfrescoNavigationHandler.java b/source/java/org/alfresco/web/app/AlfrescoNavigationHandler.java index fe95708dfa..978bf86817 100644 --- a/source/java/org/alfresco/web/app/AlfrescoNavigationHandler.java +++ b/source/java/org/alfresco/web/app/AlfrescoNavigationHandler.java @@ -266,11 +266,18 @@ public class AlfrescoNavigationHandler extends NavigationHandler if (dispatchContext != null) { + if (logger.isDebugEnabled()) + logger.debug("Using dispatch context for dialog lookup: " + + dispatchContext.getType().toString()); + // use the node to perform the lookup (this will include the global section) config = configSvc.getConfig(dispatchContext); } else { + if (logger.isDebugEnabled()) + logger.debug("Looking up dialog in global config"); + // just use the global config = configSvc.getGlobalConfig(); } @@ -306,11 +313,18 @@ public class AlfrescoNavigationHandler extends NavigationHandler if (dispatchContext != null) { + if (logger.isDebugEnabled()) + logger.debug("Using dispatch context for wizard lookup: " + + dispatchContext.getType().toString()); + // use the node to perform the lookup (this will include the global section) config = configSvc.getConfig(dispatchContext); } else { + if (logger.isDebugEnabled()) + logger.debug("Looking up wizard in global config"); + // just use the global config = configSvc.getGlobalConfig(); } diff --git a/source/java/org/alfresco/web/app/Application.java b/source/java/org/alfresco/web/app/Application.java index 04552ed611..1f9e5b03a2 100644 --- a/source/java/org/alfresco/web/app/Application.java +++ b/source/java/org/alfresco/web/app/Application.java @@ -38,6 +38,7 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.web.app.servlet.AuthenticationHelper; import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.ErrorBean; +import org.alfresco.web.bean.dashboard.DashboardManager; import org.alfresco.web.bean.dialog.DialogManager; import org.alfresco.web.bean.repository.User; import org.alfresco.web.bean.wizard.WizardManager; @@ -189,6 +190,16 @@ public class Application return (WizardManager)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "WizardManager"); } + /** + * Retrieves the DashboardManager managed bean + * + * @return DashboardManager bean + */ + public static DashboardManager getDashboardManager() + { + return (DashboardManager)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "DashboardManager"); + } + /** * Retrieves the configured error page for the application * diff --git a/source/java/org/alfresco/web/app/servlet/BaseServlet.java b/source/java/org/alfresco/web/app/servlet/BaseServlet.java index 7a252331bc..90b4c7c687 100644 --- a/source/java/org/alfresco/web/app/servlet/BaseServlet.java +++ b/source/java/org/alfresco/web/app/servlet/BaseServlet.java @@ -66,10 +66,10 @@ public abstract class BaseServlet extends HttpServlet static { validRedirectJSPs.add("/jsp/browse/browse.jsp"); - validRedirectJSPs.add("/jsp/browse/dashboard.jsp"); validRedirectJSPs.add("/jsp/admin/admin-console.jsp"); validRedirectJSPs.add("/jsp/admin/node-browser.jsp"); validRedirectJSPs.add("/jsp/admin/store-browser.jsp"); + validRedirectJSPs.add("/jsp/users/user-console.jsp"); validRedirectJSPs.add("/jsp/categories/categories.jsp"); validRedirectJSPs.add("/jsp/dialog/about.jsp"); validRedirectJSPs.add("/jsp/dialog/advanced-search.jsp"); @@ -77,6 +77,7 @@ public abstract class BaseServlet extends HttpServlet validRedirectJSPs.add("/jsp/forums/forums.jsp"); validRedirectJSPs.add("/jsp/users/users.jsp"); validRedirectJSPs.add("/jsp/trashcan/trash-list.jsp"); + validRedirectJSPs.add("/jsp/dashboards/container.jsp"); } private static Log logger = LogFactory.getLog(BaseServlet.class); @@ -103,8 +104,22 @@ public abstract class BaseServlet extends HttpServlet * * @throws IOException */ - public AuthenticationStatus servletAuthenticate(HttpServletRequest req, HttpServletResponse res) + public AuthenticationStatus servletAuthenticate(HttpServletRequest req, HttpServletResponse res) throws IOException + { + return servletAuthenticate(req, res, true); + } + + /** + * Perform an authentication for the servlet request URI. Processing any "ticket" or + * "guest" URL arguments. + * + * @return AuthenticationStatus + * + * @throws IOException + */ + public AuthenticationStatus servletAuthenticate(HttpServletRequest req, HttpServletResponse res, + boolean redirectToLoginPage) throws IOException { AuthenticationStatus status; @@ -124,9 +139,9 @@ public abstract class BaseServlet extends HttpServlet } status = AuthenticationHelper.authenticate(getServletContext(), req, res, forceGuest); } - if (status == AuthenticationStatus.Failure) + if (status == AuthenticationStatus.Failure && redirectToLoginPage) { - // authentication failed - now need to display the login page to the user + // authentication failed - now need to display the login page to the user, if asked to redirectToLoginPage(req, res, getServletContext()); } diff --git a/source/java/org/alfresco/web/app/servlet/CommandServlet.java b/source/java/org/alfresco/web/app/servlet/CommandServlet.java index 2ccfb0ed40..0beb509ddc 100644 --- a/source/java/org/alfresco/web/app/servlet/CommandServlet.java +++ b/source/java/org/alfresco/web/app/servlet/CommandServlet.java @@ -47,7 +47,7 @@ import org.apache.commons.logging.LogFactory; * The 'processor-name' identifies the command processor to execute the command. For example the * 'workflow' processor will execute workflow commands upon a node (e.g. "approve" or "reject"). * For example: - *
/alfresco/command/workflow/approve/workspace/SpacesStore/0000-0000-0000-0000
+ * 
/alfresco/command/workflow/approve/workspace/SpacesStore/0000-0000-0000-0000
* The store protocol, followed by the store ID, followed by the content Node Id used to * identify the node to execute the workflow action upon. *

diff --git a/source/java/org/alfresco/web/app/servlet/TemplateContentServlet.java b/source/java/org/alfresco/web/app/servlet/TemplateContentServlet.java index 8d51790e69..11cc65633d 100644 --- a/source/java/org/alfresco/web/app/servlet/TemplateContentServlet.java +++ b/source/java/org/alfresco/web/app/servlet/TemplateContentServlet.java @@ -261,7 +261,8 @@ public class TemplateContentServlet extends BaseServlet private Object getModel(ServiceRegistry services, HttpServletRequest req, NodeRef templateRef, NodeRef nodeRef) { // build FreeMarker default model and merge - Map root = DefaultModelHelper.buildDefaultModel(services, Application.getCurrentUser(req.getSession())); + Map root = DefaultModelHelper.buildDefaultModel( + services, Application.getCurrentUser(req.getSession()), templateRef); // put the current NodeRef in as "space" and "document" TemplateNode node = new TemplateNode(nodeRef, services, this.imageResolver); diff --git a/source/java/org/alfresco/web/app/servlet/ajax/AjaxCommand.java b/source/java/org/alfresco/web/app/servlet/ajax/AjaxCommand.java new file mode 100644 index 0000000000..17eba223be --- /dev/null +++ b/source/java/org/alfresco/web/app/servlet/ajax/AjaxCommand.java @@ -0,0 +1,37 @@ +package org.alfresco.web.app.servlet.ajax; + +import java.io.IOException; + +import javax.faces.context.FacesContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Interface for all Ajax commands executed by this servlet. + * + * The method is responsible for invoking the underlying managed bean + * and dealing with the response. + * + * @author gavinc + */ +public interface AjaxCommand +{ + /** + * Invokes the relevant method on the bean represented by the given + * expression. Parameters required to call the method can be retrieved + * from the request. + * + * Currently the content type of the response will always be text/html, in the + * future sublcasses may provide a mechanism to allow the content type to be set + * dynamically. + * + * @param facesContext FacesContext + * @param expression The binding expression + * @param request The request + * @param response The response + */ + public abstract void execute(FacesContext facesContext, String expression, + HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException; +} diff --git a/source/java/org/alfresco/web/app/servlet/ajax/AjaxServlet.java b/source/java/org/alfresco/web/app/servlet/ajax/AjaxServlet.java new file mode 100644 index 0000000000..20d5d07938 --- /dev/null +++ b/source/java/org/alfresco/web/app/servlet/ajax/AjaxServlet.java @@ -0,0 +1,184 @@ +package org.alfresco.web.app.servlet.ajax; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.StringTokenizer; + +import javax.faces.context.FacesContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.web.app.servlet.AuthenticationStatus; +import org.alfresco.web.app.servlet.BaseServlet; +import org.alfresco.web.app.servlet.FacesHelper; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Servlet responsible for processing AJAX requests. + * + * The URL to the servlet should be in the form: + *

/alfresco/ajax/command/Bean.binding.expression
+ *

+ * See http://wiki.alfresco.com/wiki/AJAX_Support for details. + *

+ * Like most Alfresco servlets, the URL may be followed by a valid 'ticket' argument for authentication: + * ?ticket=1234567890 + * + * @author gavinc + */ +public class AjaxServlet extends BaseServlet +{ + public static final String AJAX_LOG_KEY = "alfresco.ajax"; + + protected enum Command { invoke, get, set}; + + private static final long serialVersionUID = -7654769105419391840L; + private static Log logger = LogFactory.getLog(AJAX_LOG_KEY); + private static Log headersLogger = LogFactory.getLog(AJAX_LOG_KEY + ".headers"); + private static Log perfLogger = LogFactory.getLog(AJAX_LOG_KEY + ".performance"); + + /** + * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + protected void service(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + long startTime = 0; + + try + { + String uri = request.getRequestURI(); + + if (logger.isDebugEnabled()) + { + String queryString = request.getQueryString(); + logger.debug("Processing URL: " + uri + + ((queryString != null && queryString.length() > 0) ? ("?" + queryString) : "")); + } + + // dump the request headers + if (headersLogger.isDebugEnabled()) + { + Enumeration headers = request.getHeaderNames(); + while (headers.hasMoreElements()) + { + String name = (String)headers.nextElement(); + headersLogger.debug(name + ": " + request.getHeader(name)); + } + } + + // Make sure the user is authenticated, if not throw an error to return the + // 500 Internal Server Error code back to the client + AuthenticationStatus status = servletAuthenticate(request, response, false); + if (status == AuthenticationStatus.Failure) + { + throw new AlfrescoRuntimeException("Access Denied: User not authenticated"); + } + + uri = uri.substring(request.getContextPath().length()); + StringTokenizer t = new StringTokenizer(uri, "/"); + int tokenCount = t.countTokens(); + if (tokenCount < 3) + { + throw new AlfrescoRuntimeException("Servlet URL did not contain all required args: " + uri); + } + + // skip the servlet name + t.nextToken(); + + // retrieve the command from the URL + String commandName = t.nextToken(); + + // retrieve the binding expression from the URL + String expression = t.nextToken(); + + // setup the faces context + FacesContext facesContext = FacesHelper.getFacesContext(request, response, getServletContext()); + + // start a timer + if (perfLogger.isDebugEnabled()) + startTime = System.currentTimeMillis(); + + // instantiate the relevant command + AjaxCommand command = null; + if (Command.invoke.toString().equals(commandName)) + { + command = new InvokeCommand(); + } + else if (Command.get.toString().equals(commandName)) + { + command = new GetCommand(); + } + else + { + throw new AlfrescoRuntimeException("Unrecognised command received: " + commandName); + } + + // execute the command + command.execute(facesContext, expression, request, response); + } + catch (RuntimeException error) + { + handleError(response, error); + } + finally + { + // measure the time taken + if (perfLogger.isDebugEnabled()) + { + long endTime = System.currentTimeMillis(); + perfLogger.debug("Time to execute command: " + (endTime - startTime) + "ms"); + } + } + } + + /** + * Handles any error that occurs during the execution of the servlet + * + * @param response The response + * @param cause The cause of the error + */ + protected void handleError(HttpServletResponse response, RuntimeException cause) + throws ServletException, IOException + { + // if we can send back the 500 error with the error from the top of the + // stack as the error status message. + + // NOTE: if we use the built in support for generating error pages for + // 500 errors we can tailor the output for AJAX calls so that the + // body of the response can be used to show the error details. + + if (!response.isCommitted()) + { + // dump the error if debugging is enabled + if (logger.isDebugEnabled()) + { + logger.error(cause); + Throwable theCause = cause.getCause(); + if (theCause != null) + { + logger.error("caused by: ", theCause); + } + } + + // extract a message from the exception + String msg = cause.getMessage(); + if (msg == null) + { + msg = cause.toString(); + } + + // send the error + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg); + } + else + { + // the response has already been comitted, not much we can do but + // let the error through and let the container deal with it + throw cause; + } + } +} diff --git a/source/java/org/alfresco/web/app/servlet/ajax/BaseAjaxCommand.java b/source/java/org/alfresco/web/app/servlet/ajax/BaseAjaxCommand.java new file mode 100644 index 0000000000..0ed97ccbc4 --- /dev/null +++ b/source/java/org/alfresco/web/app/servlet/ajax/BaseAjaxCommand.java @@ -0,0 +1,19 @@ +package org.alfresco.web.app.servlet.ajax; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Base class for all Ajax based commands + * + * @author gavinc + */ +public abstract class BaseAjaxCommand implements AjaxCommand +{ + protected static Log logger = LogFactory.getLog(AjaxServlet.AJAX_LOG_KEY); + + public String makeBindingExpression(String expression) + { + return "#{" + expression + "}"; + } +} diff --git a/source/java/org/alfresco/web/app/servlet/ajax/GetCommand.java b/source/java/org/alfresco/web/app/servlet/ajax/GetCommand.java new file mode 100644 index 0000000000..b513e27154 --- /dev/null +++ b/source/java/org/alfresco/web/app/servlet/ajax/GetCommand.java @@ -0,0 +1,69 @@ +package org.alfresco.web.app.servlet.ajax; + +import java.io.IOException; + +import javax.faces.context.FacesContext; +import javax.faces.el.ValueBinding; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.transaction.UserTransaction; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.web.bean.repository.Repository; + +/** + * Command that executes the given value binding expression. + *

+ * This command is intended to be used for calling existing managed + * bean methods. The result of the value binding is added to + * the response as is i.e. by calling toString(). + * The content type of the response is always text/html. + * + * @author gavinc + */ +public class GetCommand extends BaseAjaxCommand +{ + public void execute(FacesContext facesContext, String expression, + HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + // create the JSF binding expression + String bindingExpr = makeBindingExpression(expression); + + if (logger.isDebugEnabled()) + logger.debug("Retrieving value from value binding: " + bindingExpr); + + UserTransaction tx = null; + try + { + // create the value binding + ValueBinding binding = facesContext.getApplication(). + createValueBinding(bindingExpr); + + if (binding != null) + { + // setup the transaction + tx = Repository.getUserTransaction(facesContext, true); + tx.begin(); + + // get the value from the value binding + Object value = binding.getValue(facesContext); + if (value != null) + { + response.getWriter().write(value.toString()); + } + + // commit + tx.commit(); + } + } + catch (Throwable err) + { + // rollback the transaction + try { if (tx != null) {tx.rollback();} } catch (Exception ex) {} + + throw new AlfrescoRuntimeException("Failed to retrieve value: " + err.getMessage(), err); + } + } +} diff --git a/source/java/org/alfresco/web/app/servlet/ajax/InvokeCommand.java b/source/java/org/alfresco/web/app/servlet/ajax/InvokeCommand.java new file mode 100644 index 0000000000..3c5e905804 --- /dev/null +++ b/source/java/org/alfresco/web/app/servlet/ajax/InvokeCommand.java @@ -0,0 +1,97 @@ +package org.alfresco.web.app.servlet.ajax; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; + +import javax.faces.FactoryFinder; +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; +import javax.faces.context.ResponseWriter; +import javax.faces.el.MethodBinding; +import javax.faces.render.RenderKit; +import javax.faces.render.RenderKitFactory; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.transaction.UserTransaction; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.web.bean.repository.Repository; + +/** + * Command that invokes the method represented by the expression. + *

+ * The managed bean method called is responsible for writing the response + * by getting hold of the JSF ResponseWriter. Parameters can also be + * retrieved via the JSF ExternalContext object. + *

+ * In a future release (if required) annotations may be used to state + * what content type to use for the response. + * + * @author gavinc + */ +public class InvokeCommand extends BaseAjaxCommand +{ + public void execute(FacesContext facesContext, String expression, + HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + // setup the JSF response writer. + + // NOTE: it doesn't seem to matter what the content type of the response is (at least with Dojo), + // it determines it's behaviour from the mimetype specified in the AJAX call on the client, + // therefore, for now we will always return a content type of text/html. + // In the future we may use annotations on the method to be called to specify what content + // type should be used for the response. + + OutputStream os = response.getOutputStream(); + UIViewRoot viewRoot = facesContext.getViewRoot(); + RenderKitFactory renderFactory = (RenderKitFactory)FactoryFinder. + getFactory(FactoryFinder.RENDER_KIT_FACTORY); + RenderKit renderKit = renderFactory.getRenderKit(facesContext, + viewRoot.getRenderKitId()); + ResponseWriter writer = renderKit.createResponseWriter( + new OutputStreamWriter(os), MimetypeMap.MIMETYPE_HTML, "UTF-8"); + facesContext.setResponseWriter(writer); + response.setContentType(writer.getContentType()); + + // create the JSF binding expression + String bindingExpr = makeBindingExpression(expression); + + if (logger.isDebugEnabled()) + logger.debug("Invoking method represented by " + bindingExpr); + + UserTransaction tx = null; + try + { + // create the method binding from the expression + MethodBinding binding = facesContext.getApplication().createMethodBinding( + bindingExpr, new Class[] {}); + + if (binding != null) + { + // setup the transaction + tx = Repository.getUserTransaction(facesContext); + tx.begin(); + + // invoke the method + binding.invoke(facesContext, new Object[] {}); + + // commit + tx.commit(); + } + } + catch (Throwable err) + { + // rollback the transaction + try { if (tx != null) {tx.rollback();} } catch (Exception ex) {} + + throw new AlfrescoRuntimeException("Failed to execute method: " + err.getMessage(), err); + } + + // force the output back to the client + writer.close(); + } +} diff --git a/source/java/org/alfresco/web/bean/AdminNodeBrowseBean.java b/source/java/org/alfresco/web/bean/AdminNodeBrowseBean.java index ad3ed8102b..6084b72d36 100644 --- a/source/java/org/alfresco/web/bean/AdminNodeBrowseBean.java +++ b/source/java/org/alfresco/web/bean/AdminNodeBrowseBean.java @@ -768,7 +768,7 @@ public class AdminNodeBrowseBean /** * Permission representing the fact that "Read Permissions" has not been granted */ - public class NoReadPermissionGranted + public static class NoReadPermissionGranted { public String getPermission() { diff --git a/source/java/org/alfresco/web/bean/AdvancedSearchBean.java b/source/java/org/alfresco/web/bean/AdvancedSearchBean.java index 44047c6587..05f2451530 100644 --- a/source/java/org/alfresco/web/bean/AdvancedSearchBean.java +++ b/source/java/org/alfresco/web/bean/AdvancedSearchBean.java @@ -1531,7 +1531,11 @@ public class AdvancedSearchBean AspectDefinition aspectDef = dd.getAspect(aspect); propDef = aspectDef.getProperties().get(propQName); } - customPropertyLookup.put(propQName.toString(), propDef.getDataType()); + + if (propQName != null && propDef != null) + { + customPropertyLookup.put(propQName.toString(), propDef.getDataType()); + } } } } diff --git a/source/java/org/alfresco/web/bean/BrowseBean.java b/source/java/org/alfresco/web/bean/BrowseBean.java index 3c8b7c57df..12e283bc33 100644 --- a/source/java/org/alfresco/web/bean/BrowseBean.java +++ b/source/java/org/alfresco/web/bean/BrowseBean.java @@ -1350,117 +1350,38 @@ public class BrowseBean implements IContextListener } /** - * Handler called upon the completion of the Delete Space page + * Removes the given node from the breadcrumb i.e. following a delete * - * @return outcome + * @param node The space to remove from the breadcrumb */ - public String deleteSpaceOK() + public void removeSpaceFromBreadcrumb(Node node) { - String outcome = null; - - Node node = getActionSpace(); - if (node != null) + List location = navigator.getLocation(); + IBreadcrumbHandler handler = location.get(location.size() - 1); + if (handler instanceof BrowseBreadcrumbHandler) { - try + // see if the current breadcrumb location is our node + if ( ((BrowseBreadcrumbHandler)handler).getNodeRef().equals(node.getNodeRef()) == true ) { - if (logger.isDebugEnabled()) - logger.debug("Trying to delete space: " + node.getId()); + location.remove(location.size() - 1); - this.nodeService.deleteNode(node.getNodeRef()); - - // remove this node from the breadcrumb if required - List location = navigator.getLocation(); - IBreadcrumbHandler handler = location.get(location.size() - 1); - if (handler instanceof BrowseBreadcrumbHandler) + // now work out which node to set the list to refresh against + if (location.size() != 0) { - // see if the current breadcrumb location is our node - if ( ((BrowseBreadcrumbHandler)handler).getNodeRef().equals(node.getNodeRef()) == true ) + handler = location.get(location.size() - 1); + if (handler instanceof BrowseBreadcrumbHandler) { - location.remove(location.size() - 1); - - // now work out which node to set the list to refresh against - if (location.size() != 0) - { - handler = location.get(location.size() - 1); - if (handler instanceof BrowseBreadcrumbHandler) - { - // change the current node Id - navigator.setCurrentNodeId(((BrowseBreadcrumbHandler)handler).getNodeRef().getId()); - } - else - { - // TODO: shouldn't do this - but for now the user home dir is the root! - navigator.setCurrentNodeId(Application.getCurrentUser(FacesContext.getCurrentInstance()).getHomeSpaceId()); - } - } + // change the current node Id + navigator.setCurrentNodeId(((BrowseBreadcrumbHandler)handler).getNodeRef().getId()); + } + else + { + // TODO: shouldn't do this - but for now the user home dir is the root! + navigator.setCurrentNodeId(Application.getCurrentUser(FacesContext.getCurrentInstance()).getHomeSpaceId()); } } - - // add a message to inform the user that the delete was OK - String statusMsg = MessageFormat.format( - Application.getMessage(FacesContext.getCurrentInstance(), "status_space_deleted"), - new Object[]{node.getName()}); - Utils.addStatusMessage(FacesMessage.SEVERITY_INFO, statusMsg); - - // clear action context - setActionSpace(null); - - // setting the outcome will show the browse view again - outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + - AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse"; - } - catch (Throwable err) - { - Utils.addErrorMessage(Application.getMessage( - FacesContext.getCurrentInstance(), MSG_ERROR_DELETE_SPACE) + err.getMessage(), err); } } - else - { - logger.warn("WARNING: deleteSpaceOK called without a current Space!"); - } - - return outcome; - } - - /** - * Handler called upon the completion of the Delete File page - * - * @return outcome - */ - public String deleteFileOK() - { - String outcome = null; - - Node node = getDocument(); - if (node != null) - { - try - { - if (logger.isDebugEnabled()) - logger.debug("Trying to delete content node: " + node.getId()); - - this.nodeService.deleteNode(node.getNodeRef()); - - // clear action context - setDocument(null); - - // setting the outcome will show the browse view again - outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + - AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse"; - } - catch (Throwable err) - { - Utils.addErrorMessage(Application.getMessage( - FacesContext.getCurrentInstance(), MSG_ERROR_DELETE_FILE) + err.getMessage(), err); - } - } - else - { - logger.warn("WARNING: deleteFileOK called without a current Document!"); - } - - return outcome; } /** @@ -1724,8 +1645,6 @@ public class BrowseBean implements IContextListener private static final String PAGE_NAME_BROWSE = "browse"; /** I18N messages */ - private static final String MSG_ERROR_DELETE_FILE = "error_delete_file"; - private static final String MSG_ERROR_DELETE_SPACE = "error_delete_space"; private static final String MSG_DELETE_COMPANYROOT = "delete_companyroot_confirm"; private static final String MSG_SEARCH_MINIMUM = "search_minimum"; diff --git a/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java b/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java index c40d85ac97..4e8679ed3d 100644 --- a/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java +++ b/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java @@ -58,6 +58,14 @@ public class CheckinCheckoutBean // ------------------------------------------------------------------------------ // Bean property getters and setters + /** + * @param navigator The NavigationBean to set. + */ + public void setNavigator(NavigationBean navigator) + { + this.navigator = navigator; + } + /** * @return Returns the BrowseBean. */ @@ -535,6 +543,7 @@ public class CheckinCheckoutBean String id = params.get("id"); if (id != null && id.length() != 0) { + boolean editingInline = false; Node node = setupContentDocument(id); // detect the inline editing aspect to see which edit mode to use @@ -544,50 +553,44 @@ public class CheckinCheckoutBean { // retrieve the content reader for this node ContentReader reader = getContentService().getReader(node.getNodeRef(), ContentModel.PROP_CONTENT); - String mimetype = reader.getMimetype(); - - // calculate which editor screen to display - if (MimetypeMap.MIMETYPE_TEXT_PLAIN.equals(mimetype) || - MimetypeMap.MIMETYPE_XML.equals(mimetype) || - MimetypeMap.MIMETYPE_TEXT_CSS.equals(mimetype) || - MimetypeMap.MIMETYPE_JAVASCRIPT.equals(mimetype)) + if (reader != null) { - // make content available to the editing screen - if (reader != null) + editingInline = true; + String mimetype = reader.getMimetype(); + + // calculate which editor screen to display + if (MimetypeMap.MIMETYPE_TEXT_PLAIN.equals(mimetype) || + MimetypeMap.MIMETYPE_XML.equals(mimetype) || + MimetypeMap.MIMETYPE_TEXT_CSS.equals(mimetype) || + MimetypeMap.MIMETYPE_JAVASCRIPT.equals(mimetype)) { + // make content available to the editing screen setEditorOutput(reader.getContentString()); + + // navigate to appropriate screen + FacesContext fc = FacesContext.getCurrentInstance(); + this.navigator.setupDispatchContext(node); + fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "editTextInline"); } else { - setEditorOutput(""); - } - - // navigate to appropriate screen - FacesContext fc = FacesContext.getCurrentInstance(); - fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "editTextInline"); - } - else - { - // make content available to the editing screen - if (reader != null) - { + // make content available to the editing screen setDocumentContent(reader.getContentString()); + setEditorOutput(null); + + // navigate to appropriate screen + FacesContext fc = FacesContext.getCurrentInstance(); + this.navigator.setupDispatchContext(node); + fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "editHtmlInline"); } - else - { - setDocumentContent(""); - } - setEditorOutput(null); - - // navigate to appropriate screen - FacesContext fc = FacesContext.getCurrentInstance(); - fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "editHtmlInline"); } } - else + + if (editingInline == false) { // normal downloadable document FacesContext fc = FacesContext.getCurrentInstance(); + this.navigator.setupDispatchContext(node); fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "editFile"); } } @@ -750,7 +753,6 @@ public class CheckinCheckoutBean // we can either checkin the content from the current working copy node // which would have been previously updated by the user String contentUrl; - String mimetype; if (getCopyLocation().equals(COPYLOCATION_CURRENT)) { ContentData contentData = (ContentData) node.getProperties().get(ContentModel.PROP_CONTENT); @@ -785,11 +787,9 @@ public class CheckinCheckoutBean props.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR); } - NodeRef originalDoc = this.versionOperationsService.checkin( - node.getNodeRef(), - props, - contentUrl, - this.keepCheckedOut); + // perform the checkin + this.versionOperationsService.checkin(node.getNodeRef(), + props, contentUrl, this.keepCheckedOut); // commit the transaction tx.commit(); @@ -941,6 +941,9 @@ public class CheckinCheckoutBean /** The BrowseBean to be used by the bean */ protected BrowseBean browseBean; + /** The NavigationBean bean reference */ + protected NavigationBean navigator; + /** The NodeService to be used by the bean */ protected NodeService nodeService; diff --git a/source/java/org/alfresco/web/bean/ExportBean.java b/source/java/org/alfresco/web/bean/ExportBean.java index f719191f48..8bcc77e14e 100644 --- a/source/java/org/alfresco/web/bean/ExportBean.java +++ b/source/java/org/alfresco/web/bean/ExportBean.java @@ -103,7 +103,7 @@ public class ExportBean params.put(ExporterActionExecuter.PARAM_PACKAGE_NAME, this.packageName); params.put(ExporterActionExecuter.PARAM_ENCODING, this.encoding); params.put(ExporterActionExecuter.PARAM_DESTINATION_FOLDER, this.destination); - params.put(ExporterActionExecuter.PARAM_INCLUDE_CHILDREN, new Boolean(includeChildren)); + params.put(ExporterActionExecuter.PARAM_INCLUDE_CHILDREN, Boolean.valueOf(includeChildren)); params.put(ExporterActionExecuter.PARAM_INCLUDE_SELF, new Boolean(includeSelf)); action = this.actionService.createAction(ExporterActionExecuter.NAME, params); } diff --git a/source/java/org/alfresco/web/bean/GroupsBean.java b/source/java/org/alfresco/web/bean/GroupsBean.java index 58b5c1de4a..5ee6f4a2ef 100644 --- a/source/java/org/alfresco/web/bean/GroupsBean.java +++ b/source/java/org/alfresco/web/bean/GroupsBean.java @@ -40,6 +40,7 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.AuthorityType; +import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.web.app.Application; @@ -568,16 +569,21 @@ public class GroupsBean implements IContextListener services.getNamespaceService(), false); - items = new SelectItem[nodes.size()]; - for (int index=0; index itemList = new ArrayList(nodes.size()); + for (NodeRef personRef : nodes) { - NodeRef personRef = nodes.get(index); - String firstName = (String)this.nodeService.getProperty(personRef, ContentModel.PROP_FIRSTNAME); - String lastName = (String)this.nodeService.getProperty(personRef, ContentModel.PROP_LASTNAME); String username = (String)this.nodeService.getProperty(personRef, ContentModel.PROP_USERNAME); - SelectItem item = new SortableSelectItem(username, firstName + " " + lastName, lastName); - items[index] = item; + if (PermissionService.GUEST_AUTHORITY.equals(username) == false) + { + String firstName = (String)this.nodeService.getProperty(personRef, ContentModel.PROP_FIRSTNAME); + String lastName = (String)this.nodeService.getProperty(personRef, ContentModel.PROP_LASTNAME); + + SelectItem item = new SortableSelectItem(username, firstName + " " + lastName, lastName); + itemList.add(item); + } } + items = new SelectItem[itemList.size()]; + itemList.toArray(items); // commit the transaction tx.commit(); diff --git a/source/java/org/alfresco/web/bean/LinkPropertiesBean.java b/source/java/org/alfresco/web/bean/LinkPropertiesBean.java index f45ae9d1de..6e3c071dbc 100644 --- a/source/java/org/alfresco/web/bean/LinkPropertiesBean.java +++ b/source/java/org/alfresco/web/bean/LinkPropertiesBean.java @@ -137,7 +137,7 @@ public class LinkPropertiesBean Map props = this.editableNode.getProperties(); // get the name and move the node as necessary - String name = (String)props.get(ContentModel.PROP_NAME); + //String name = (String)props.get(ContentModel.PROP_NAME); //if (name != null) //{ // fileFolderService.rename(nodeRef, name); diff --git a/source/java/org/alfresco/web/bean/NavigationBean.java b/source/java/org/alfresco/web/bean/NavigationBean.java index 0cc97b2301..57a7f07158 100644 --- a/source/java/org/alfresco/web/bean/NavigationBean.java +++ b/source/java/org/alfresco/web/bean/NavigationBean.java @@ -62,6 +62,10 @@ import org.apache.log4j.Logger; */ public class NavigationBean { + private static final String OUTCOME_MYALFRESCO = "myalfresco"; + + private static final String OUTCOME_BROWSE = "browse"; + /** * Default constructor */ @@ -394,10 +398,18 @@ public class NavigationBean { ContentContext contentCtx = (ContentContext) diskShare.getContext(); NodeRef rootNode = contentCtx.getRootNode(); - String cifsPath = Repository.getNamePath(this.nodeService, path, rootNode, "\\", "file:///" + getCIFSServerPath(diskShare)); + try + { + String cifsPath = Repository.getNamePath(this.nodeService, path, rootNode, "\\", "file:///" + getCIFSServerPath(diskShare)); - node.getProperties().put("cifsPath", cifsPath); - node.getProperties().put("cifsPathLabel", cifsPath.substring(8)); // strip file:/// part + node.getProperties().put("cifsPath", cifsPath); + node.getProperties().put("cifsPathLabel", cifsPath.substring(8)); // strip file:/// part + } + catch(AccessDeniedException ade) + { + node.getProperties().put("cifsPath", ""); + node.getProperties().put("cifsPathLabel",""); // strip file:/// part + } } this.currentNode = node; @@ -587,6 +599,9 @@ public class NavigationBean elements.add(new NavigationBreadcrumbHandler(companyHome.getNodeRef(), companyHome.getName())); setLocation(elements); setCurrentNodeId(companyHome.getId()); + + // we need to force a navigation to refresh the browse screen breadcrumb + context.getApplication().getNavigationHandler().handleNavigation(context, null, OUTCOME_BROWSE); } else if (LOCATION_HOME.equals(location)) { @@ -597,6 +612,9 @@ public class NavigationBean elements.add(new NavigationBreadcrumbHandler(homeSpaceRef, homeSpaceName)); setLocation(elements); setCurrentNodeId(homeSpaceRef.getId()); + + // we need to force a navigation to refresh the browse screen breadcrumb + context.getApplication().getNavigationHandler().handleNavigation(context, null, OUTCOME_BROWSE); } else if (LOCATION_GUEST.equals(location)) { @@ -605,10 +623,31 @@ public class NavigationBean elements.add(new NavigationBreadcrumbHandler(guestHome.getNodeRef(), guestHome.getName())); setLocation(elements); setCurrentNodeId(guestHome.getId()); + + // we need to force a navigation to refresh the browse screen breadcrumb + context.getApplication().getNavigationHandler().handleNavigation(context, null, OUTCOME_BROWSE); + } + else if (LOCATION_DASHBOARD.equals(location)) + { + List elements = new ArrayList(1); + elements.add(new IBreadcrumbHandler() + { + public String navigationOutcome(UIBreadcrumb breadcrumb) + { + setLocation( (List)breadcrumb.getValue() ); + return OUTCOME_MYALFRESCO; + }; + + public String toString() + { + return Application.getMessage(FacesContext.getCurrentInstance(), MSG_MYALFRESCO); + }; + }); + setLocation(elements); + + // we need to force a navigation to refresh the browse screen breadcrumb + context.getApplication().getNavigationHandler().handleNavigation(context, null, OUTCOME_MYALFRESCO); } - - // we need to force a navigation to refresh the browse screen breadcrumb - context.getApplication().getNavigationHandler().handleNavigation(context, null, "browse"); } catch (InvalidNodeRefException refErr) { @@ -711,7 +750,7 @@ public class NavigationBean } else { - return "browse"; + return OUTCOME_BROWSE; } } @@ -734,6 +773,9 @@ public class NavigationBean private static final String LOCATION_COMPANY = "company"; private static final String LOCATION_HOME = "home"; private static final String LOCATION_GUEST = "guest"; + private static final String LOCATION_DASHBOARD = "dashboard"; + + private static final String MSG_MYALFRESCO = "my_alfresco"; private static final String ERROR_DELETED_FOLDER = "error_deleted_folder"; diff --git a/source/java/org/alfresco/web/bean/SearchContext.java b/source/java/org/alfresco/web/bean/SearchContext.java index f100d0d4d8..cf5b0855e1 100644 --- a/source/java/org/alfresco/web/bean/SearchContext.java +++ b/source/java/org/alfresco/web/bean/SearchContext.java @@ -225,7 +225,11 @@ public final class SearchContext implements Serializable } // special case for AND all terms if set (apply after operator character removed) - operatorAND = operatorAND | this.forceAndTerms; + // note that we can't force AND if NOT operator has been set + if (operatorNOT == false) + { + operatorAND = operatorAND | this.forceAndTerms; + } if (term.length() != 0) { diff --git a/source/java/org/alfresco/web/bean/SpaceDetailsBean.java b/source/java/org/alfresco/web/bean/SpaceDetailsBean.java index ae8d7c67b6..d55818b869 100644 --- a/source/java/org/alfresco/web/bean/SpaceDetailsBean.java +++ b/source/java/org/alfresco/web/bean/SpaceDetailsBean.java @@ -16,31 +16,28 @@ */ package org.alfresco.web.bean; +import java.io.Serializable; import java.text.MessageFormat; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; import javax.transaction.UserTransaction; import org.alfresco.model.ContentModel; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.TemplateImageResolver; import org.alfresco.service.cmr.repository.TemplateNode; -import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.namespace.QName; import org.alfresco.web.app.AlfrescoNavigationHandler; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.ui.common.Utils; -import org.alfresco.web.ui.common.Utils.URLMode; import org.alfresco.web.ui.common.component.UIActionLink; -import org.alfresco.web.ui.common.component.UIPanel.ExpandedEvent; /** * Backing bean provided access to the details of a Space @@ -50,10 +47,19 @@ import org.alfresco.web.ui.common.component.UIPanel.ExpandedEvent; public class SpaceDetailsBean extends BaseDetailsBean { private static final String OUTCOME_RETURN = "showSpaceDetails"; + + private static final String MSG_HAS_FOLLOWING_CATEGORIES = "has_following_categories_space"; + private static final String MSG_NO_CATEGORIES_APPLIED = "no_categories_applied_space"; + private static final String MSG_ERROR_UPDATE_CATEGORY = "error_update_category"; + private static final String MSG_ERROR_ASPECT_CLASSIFY = "error_aspect_classify_space"; /** PermissionService bean reference */ protected PermissionService permissionService; + /** Category details */ + private NodeRef addedCategory; + private List categories; + // ------------------------------------------------------------------------------ // Construction @@ -161,6 +167,7 @@ public class SpaceDetailsBean extends BaseDetailsBean */ public void nextItem(ActionEvent event) { + boolean foundNextItem = false; UIActionLink link = (UIActionLink)event.getComponent(); Map params = link.getParameterMap(); String id = params.get("id"); @@ -191,9 +198,22 @@ public class SpaceDetailsBean extends BaseDetailsBean // prepare for showing details for this node this.browseBean.setupSpaceAction(next.getId(), false); + + // we found a next item + foundNextItem = true; } } - } + } + + // if we did not find a next item make sure the current node is + // in the dispatch context otherwise the details screen will go back + // to the default one. + if (foundNextItem == false) + { + NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id); + Node currNode = new Node(currNodeRef); + this.navigator.setupDispatchContext(currNode); + } } } @@ -202,6 +222,7 @@ public class SpaceDetailsBean extends BaseDetailsBean */ public void previousItem(ActionEvent event) { + boolean foundPreviousItem = false; UIActionLink link = (UIActionLink)event.getComponent(); Map params = link.getParameterMap(); String id = params.get("id"); @@ -229,9 +250,22 @@ public class SpaceDetailsBean extends BaseDetailsBean // show details for this node this.browseBean.setupSpaceAction(previous.getId(), false); + + // we found a next item + foundPreviousItem = true; } } } + + // if we did not find a previous item make sure the current node is + // in the dispatch context otherwise the details screen will go back + // to the default one. + if (foundPreviousItem == false) + { + NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id); + Node currNode = new Node(currNodeRef); + this.navigator.setupDispatchContext(currNode); + } } } @@ -244,4 +278,200 @@ public class SpaceDetailsBean extends BaseDetailsBean this.navigator.resetCurrentNodeProperties(); return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; } + + // ------------------------------------------------------------------------------ + // Categorised Details + + /** + * Determines whether the current space has any categories applied + * + * @return true if the document has categories attached + */ + public boolean isCategorised() + { + return getSpace().hasAspect(ContentModel.ASPECT_GEN_CLASSIFIABLE); + } + + /** + * Returns a list of objects representing the categories applied to the + * current space + * + * @return List of categories + */ + public String getCategoriesOverviewHTML() + { + String html = null; + + if (isCategorised()) + { + // we know for now that the general classifiable aspect only will be + // applied so we can retrive the categories property direclty + Collection categories = (Collection)this.nodeService.getProperty(getSpace().getNodeRef(), + ContentModel.PROP_CATEGORIES); + + if (categories == null || categories.size() == 0) + { + html = Application.getMessage(FacesContext.getCurrentInstance(), MSG_NO_CATEGORIES_APPLIED); + } + else + { + StringBuilder builder = new StringBuilder(Application.getMessage(FacesContext.getCurrentInstance(), + MSG_HAS_FOLLOWING_CATEGORIES)); + + builder.append("

    "); + for (Object obj : categories) + { + if (obj instanceof NodeRef) + { + if (this.nodeService.exists((NodeRef)obj)) + { + builder.append("
  • "); + builder.append(Repository.getNameForNode(this.nodeService, (NodeRef)obj)); + builder.append("
  • "); + } + } + } + builder.append("
"); + + html = builder.toString(); + } + } + + return html; + } + + /** + * Event handler called to setup the categories for editing + * + * @param event The event + */ + public void setupCategoriesForEdit(ActionEvent event) + { + this.categories = (List)this.nodeService.getProperty(getSpace().getNodeRef(), + ContentModel.PROP_CATEGORIES); + } + + /** + * Returns a Map of the initial categories on the node keyed by the NodeRef + * + * @return Map of initial categories + */ + public List getCategories() + { + return this.categories; + } + + /** + * Sets the categories Map + * + * @param categories + */ + public void setCategories(List categories) + { + this.categories = categories; + } + + /** + * Returns the last category added from the multi value editor + * + * @return The last category added + */ + public NodeRef getAddedCategory() + { + return this.addedCategory; + } + + /** + * Sets the category added from the multi value editor + * + * @param addedCategory The added category + */ + public void setAddedCategory(NodeRef addedCategory) + { + this.addedCategory = addedCategory; + } + + /** + * Updates the categories for the current document + * + * @return The outcome + */ + public String saveCategories() + { + String outcome = "cancel"; + + UserTransaction tx = null; + + try + { + tx = Repository.getUserTransaction(FacesContext.getCurrentInstance()); + tx.begin(); + + // firstly retrieve all the properties for the current node + Map updateProps = this.nodeService.getProperties( + getSpace().getNodeRef()); + + // create a node ref representation of the selected id and set the new properties + updateProps.put(ContentModel.PROP_CATEGORIES, (Serializable)this.categories); + + // set the properties on the node + this.nodeService.setProperties(getSpace().getNodeRef(), updateProps); + + // commit the transaction + tx.commit(); + + // reset the state of the current document so it reflects the changes just made + getSpace().reset(); + + outcome = "finish"; + } + catch (Throwable e) + { + try { if (tx != null) {tx.rollback();} } catch (Exception ex) {} + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + FacesContext.getCurrentInstance(), MSG_ERROR_UPDATE_CATEGORY), e.getMessage()), e); + } + + return outcome; + } + + /** + * Applies the classifiable aspect to the current document + */ + public void applyClassifiable() + { + UserTransaction tx = null; + + try + { + tx = Repository.getUserTransaction(FacesContext.getCurrentInstance()); + tx.begin(); + + // add the general classifiable aspect to the node + this.nodeService.addAspect(getSpace().getNodeRef(), ContentModel.ASPECT_GEN_CLASSIFIABLE, null); + + // commit the transaction + tx.commit(); + + // reset the state of the current document + getSpace().reset(); + } + catch (Throwable e) + { + // rollback the transaction + try { if (tx != null) {tx.rollback();} } catch (Exception ex) {} + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + FacesContext.getCurrentInstance(), MSG_ERROR_ASPECT_CLASSIFY), e.getMessage()), e); + } + } + + /** + * Returns whether the current sapce is locked + * + * @return true if the document is checked out + */ + public boolean isLocked() + { + return getSpace().isLocked(); + } } diff --git a/source/java/org/alfresco/web/bean/TrashcanBean.java b/source/java/org/alfresco/web/bean/TrashcanBean.java index 85e5d7c6cd..aa1d88f5a1 100644 --- a/source/java/org/alfresco/web/bean/TrashcanBean.java +++ b/source/java/org/alfresco/web/bean/TrashcanBean.java @@ -36,6 +36,7 @@ import org.alfresco.repo.node.archive.RestoreNodeReport.RestoreStatus; import org.alfresco.repo.search.impl.lucene.QueryParser; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; @@ -61,6 +62,8 @@ import org.alfresco.web.ui.common.component.UIModeList; import org.alfresco.web.ui.common.component.data.UIRichList; /** + * Backing bean for the Manage Deleted Items (soft delete and archiving) pages. + * * @author Kevin Roast */ public class TrashcanBean implements IContextListener @@ -535,6 +538,20 @@ public class TrashcanBean implements IContextListener } }; + private NodePropertyResolver resolverMimetype = new NodePropertyResolver() { + public Object get(Node node) { + ContentData content = (ContentData)node.getProperties().get(ContentModel.PROP_CONTENT); + return (content != null ? content.getMimetype() : null); + } + }; + + private NodePropertyResolver resolverSize = new NodePropertyResolver() { + public Object get(Node node) { + ContentData content = (ContentData)node.getProperties().get(ContentModel.PROP_CONTENT); + return (content != null ? new Long(content.getSize()) : 0L); + } + }; + private NodePropertyResolver resolverDeletedDate = new NodePropertyResolver() { public Object get(Node node) { return node.getProperties().get(ContentModel.PROP_ARCHIVED_DATE); @@ -611,6 +628,8 @@ public class TrashcanBean implements IContextListener node.addPropertyResolver("deletedDate", resolverDeletedDate); node.addPropertyResolver("deletedBy", resolverDeletedBy); node.addPropertyResolver("isFolder", resolverIsFolder); + node.addPropertyResolver("mimetype", resolverMimetype); + node.addPropertyResolver("size", resolverSize); if (this.dictionaryService.isSubClass(node.getType(), ContentModel.TYPE_FOLDER) == true && this.dictionaryService.isSubClass(node.getType(), ContentModel.TYPE_SYSTEM_FOLDER) == false) diff --git a/source/java/org/alfresco/web/bean/UserShortcutsBean.java b/source/java/org/alfresco/web/bean/UserShortcutsBean.java index 7934624a19..b4a04080ab 100644 --- a/source/java/org/alfresco/web/bean/UserShortcutsBean.java +++ b/source/java/org/alfresco/web/bean/UserShortcutsBean.java @@ -34,10 +34,9 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Node; +import org.alfresco.web.bean.repository.PreferencesService; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.component.UIActionLink; @@ -65,7 +64,7 @@ public class UserShortcutsBean /** List of shortcut nodes */ private List shortcuts = null; - private QName QNAME_SHORTCUTS = QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "shortcuts"); + private String PREF_SHORTCUTS = "shortcuts"; // ------------------------------------------------------------------------------ @@ -113,8 +112,7 @@ public class UserShortcutsBean tx.begin(); // get the shortcuts from the preferences for this user - prefRef = getShortcutsNodeRef(); - shortcuts = (List)this.nodeService.getProperty(prefRef, QNAME_SHORTCUTS); + shortcuts = (List)PreferencesService.getPreferences(context).getValue(PREF_SHORTCUTS); if (shortcuts != null) { // each shortcut node ID is persisted as a list item in a well known property @@ -184,7 +182,7 @@ public class UserShortcutsBean { shortcuts.add(this.shortcuts.get(i).getId()); } - this.nodeService.setProperty(prefRef, QNAME_SHORTCUTS, (Serializable)shortcuts); + PreferencesService.getPreferences().setValue(PREF_SHORTCUTS, (Serializable)shortcuts); } catch (Exception err) { @@ -246,14 +244,13 @@ public class UserShortcutsBean tx = Repository.getUserTransaction(context); tx.begin(); - NodeRef prefRef = getShortcutsNodeRef(); - List shortcuts = (List)this.nodeService.getProperty(prefRef, QNAME_SHORTCUTS); + List shortcuts = (List)PreferencesService.getPreferences(context).getValue(PREF_SHORTCUTS); if (shortcuts == null) { shortcuts = new ArrayList(1); } shortcuts.add(node.getNodeRef().getId()); - this.nodeService.setProperty(prefRef, QNAME_SHORTCUTS, (Serializable)shortcuts); + PreferencesService.getPreferences(context).setValue(PREF_SHORTCUTS, (Serializable)shortcuts); // commit the transaction tx.commit(); @@ -280,14 +277,6 @@ public class UserShortcutsBean } } - /** - * Get the node we need to store our user preferences - */ - private NodeRef getShortcutsNodeRef() - { - return Application.getCurrentUser(FacesContext.getCurrentInstance()).getUserPreferencesRef(); - } - /** * Action handler bound to the user shortcuts Shelf component called when a node is removed */ @@ -303,13 +292,12 @@ public class UserShortcutsBean tx = Repository.getUserTransaction(context); tx.begin(); - NodeRef prefRef = getShortcutsNodeRef(); - List shortcuts = (List)this.nodeService.getProperty(prefRef, QNAME_SHORTCUTS); + List shortcuts = (List)PreferencesService.getPreferences(context).getValue(PREF_SHORTCUTS); if (shortcuts != null && shortcuts.size() > shortcutEvent.Index) { // remove the shortcut from the saved list and persist back shortcuts.remove(shortcutEvent.Index); - this.nodeService.setProperty(prefRef, QNAME_SHORTCUTS, (Serializable)shortcuts); + PreferencesService.getPreferences(context).setValue(PREF_SHORTCUTS, (Serializable)shortcuts); // commit the transaction tx.commit(); @@ -380,13 +368,12 @@ public class UserShortcutsBean tx = Repository.getUserTransaction(context); tx.begin(); - NodeRef prefRef = getShortcutsNodeRef(); - List shortcuts = (List)this.nodeService.getProperty(prefRef, QNAME_SHORTCUTS); + List shortcuts = (List)PreferencesService.getPreferences(context).getValue(PREF_SHORTCUTS); if (shortcuts != null && shortcuts.size() > shortcutEvent.Index) { // remove the shortcut from the saved list and persist back shortcuts.remove(shortcutEvent.Index); - this.nodeService.setProperty(prefRef, QNAME_SHORTCUTS, (Serializable)shortcuts); + PreferencesService.getPreferences(context).setValue(PREF_SHORTCUTS, (Serializable)shortcuts); // commit the transaction tx.commit(); diff --git a/source/java/org/alfresco/web/bean/WorkflowUtil.java b/source/java/org/alfresco/web/bean/WorkflowUtil.java index 86e0cc2e92..8f8ed9077d 100644 --- a/source/java/org/alfresco/web/bean/WorkflowUtil.java +++ b/source/java/org/alfresco/web/bean/WorkflowUtil.java @@ -124,7 +124,7 @@ public class WorkflowUtil // first we need to take off the simpleworkflow aspect nodeService.removeAspect(ref, ContentModel.ASPECT_SIMPLE_WORKFLOW); - if (rejectMove.booleanValue()) + if (rejectMove != null && rejectMove.booleanValue()) { // move the document to the specified folder String qname = QName.createValidLocalName(docNode.getName()); diff --git a/source/java/org/alfresco/web/bean/actions/BaseActionWizard.java b/source/java/org/alfresco/web/bean/actions/BaseActionWizard.java index 373c45152f..0549966b2c 100644 --- a/source/java/org/alfresco/web/bean/actions/BaseActionWizard.java +++ b/source/java/org/alfresco/web/bean/actions/BaseActionWizard.java @@ -230,24 +230,31 @@ public abstract class BaseActionWizard extends BaseWizardBean { QName idQName = Repository.resolveToQName(child.getAttribute("name")); - // try and get the display label from config - String label = Utils.getDisplayLabel(context, child); - - // if there wasn't a client based label try and get it from the dictionary - if (label == null) + if (idQName != null) { - AspectDefinition aspectDef = this.dictionaryService.getAspect(idQName); - if (aspectDef != null) + // try and get the display label from config + String label = Utils.getDisplayLabel(context, child); + + // if there wasn't a client based label try and get it from the dictionary + if (label == null) { - label = aspectDef.getTitle(); - } - else - { - label = idQName.getLocalName(); + AspectDefinition aspectDef = this.dictionaryService.getAspect(idQName); + if (aspectDef != null) + { + label = aspectDef.getTitle(); + } + else + { + label = idQName.getLocalName(); + } } + + this.aspects.add(new SelectItem(idQName.toString(), label)); + } + else + { + logger.warn("Failed to resolve aspect '" + child.getAttribute("name") + "'"); } - - this.aspects.add(new SelectItem(idQName.toString(), label)); } // make sure the list is sorted by the label @@ -875,6 +882,11 @@ public abstract class BaseActionWizard extends BaseWizardBean } } + public int hashCode() + { + return authority.hashCode(); + } + private String name; private String authority; } diff --git a/source/java/org/alfresco/web/bean/actions/RunActionWizard.java b/source/java/org/alfresco/web/bean/actions/RunActionWizard.java index d57d42955b..0f51137e1a 100644 --- a/source/java/org/alfresco/web/bean/actions/RunActionWizard.java +++ b/source/java/org/alfresco/web/bean/actions/RunActionWizard.java @@ -10,10 +10,12 @@ import java.util.ResourceBundle; import javax.faces.context.FacesContext; import javax.faces.model.SelectItem; +import org.alfresco.repo.action.executer.CheckInActionExecuter; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ActionDefinition; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.web.app.Application; +import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.data.IDataContainer; import org.alfresco.web.data.QuickSort; @@ -25,9 +27,19 @@ import org.alfresco.web.data.QuickSort; */ public class RunActionWizard extends BaseActionWizard { + protected boolean checkinActionPresent = false; + // ------------------------------------------------------------------------------ // Wizard implementation + @Override + public void init(Map parameters) + { + super.init(parameters); + + this.checkinActionPresent = false; + } + protected String finishImpl(FacesContext context, String outcome) throws Exception { @@ -39,6 +51,12 @@ public class RunActionWizard extends BaseActionWizard String actionName = (String)actionParams.get(PROP_ACTION_NAME); this.action = actionName; + // remember the fact we have a checkin action + if (actionName.equals(CheckInActionExecuter.NAME)) + { + this.checkinActionPresent = true; + } + // get the action handler to prepare for the save Map repoActionParams = new HashMap(); IHandler handler = this.actionHandlers.get(this.action); @@ -89,7 +107,27 @@ public class RunActionWizard extends BaseActionWizard { // reset the current document properties/aspects in case we have changed them // during the execution of the custom action - this.browseBean.getDocument().reset(); + Node document = this.browseBean.getDocument(); + if (document != null) + { + document.reset(); + } + + // reset the current space properties/aspects as well in case we have + // changed them during the execution of the custom action + Node space = this.browseBean.getActionSpace(); + if (space != null) + { + space.reset(); + } + + // special case handling for checkin - if it was successful the working + // copy node the Run Action Wizard was launched against will no longer + // exist, we therefore need the client to go back to the main browse view. + if (this.checkinActionPresent) + { + outcome = "browse"; + } return outcome; } diff --git a/source/java/org/alfresco/web/bean/actions/handlers/CheckInHandler.java b/source/java/org/alfresco/web/bean/actions/handlers/CheckInHandler.java index 174727ed6e..91dfd6cd1e 100644 --- a/source/java/org/alfresco/web/bean/actions/handlers/CheckInHandler.java +++ b/source/java/org/alfresco/web/bean/actions/handlers/CheckInHandler.java @@ -23,7 +23,7 @@ public class CheckInHandler extends BaseActionHandler @Override public void setupUIDefaults(Map actionProps) { - actionProps.put(PROP_CHECKIN_MINOR, new Boolean(true)); + actionProps.put(PROP_CHECKIN_MINOR, Boolean.TRUE); } public String getJSPPath() diff --git a/source/java/org/alfresco/web/bean/ajax/NodeInfoBean.java b/source/java/org/alfresco/web/bean/ajax/NodeInfoBean.java new file mode 100644 index 0000000000..d01e995801 --- /dev/null +++ b/source/java/org/alfresco/web/bean/ajax/NodeInfoBean.java @@ -0,0 +1,128 @@ +package org.alfresco.web.bean.ajax; + +import java.io.IOException; +import java.util.Map; + +import javax.faces.context.FacesContext; +import javax.faces.context.ResponseWriter; + +import org.alfresco.model.ContentModel; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.web.bean.repository.Node; +import org.alfresco.web.bean.repository.Repository; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Bean used by an AJAX control to send information back on the + * requested node. + * + * @author gavinc + */ +public class NodeInfoBean +{ + private NodeService nodeService; + private ContentService contentService; + + private static final Log logger = LogFactory.getLog(NodeInfoBean.class); + + /** + * Returns information on the node identified by the 'noderef' + * parameter found in the ExternalContext. + *

+ * The result is the formatted HTML to show on the client. + */ + public void sendNodeInfo() throws IOException + { + FacesContext context = FacesContext.getCurrentInstance(); + ResponseWriter out = context.getResponseWriter(); + + String nodeRef = (String)context.getExternalContext().getRequestParameterMap().get("noderef"); + + if (nodeRef == null || nodeRef.length() == 0) + { + throw new IllegalArgumentException("'noderef' parameter is missing"); + } + + NodeRef repoNode = new NodeRef(nodeRef); + + if (this.nodeService.exists(repoNode)) + { + // get the client side node representation and its properties + Node clientNode = new Node(repoNode); + Map props = clientNode.getProperties(); + + // get the content size + Object content = props.get(ContentModel.PROP_CONTENT); + + // start the containing table + out.write(""); + + // write out information about the node as table rows + out.write(""); + + // add debug information to the summary if debug is enabled + if (logger.isDebugEnabled()) + { + writeRow(out, "Id:", clientNode.getId()); + writeRow(out, "Type:", clientNode.getType().toPrefixString()); + } + + writeRow(out, "Description:", (String)props.get(ContentModel.PROP_DESCRIPTION)); + writeRow(out, "Title:", (String)props.get(ContentModel.PROP_TITLE)); + writeRow(out, "Created:", props.get("created").toString()); + writeRow(out, "Modified:", props.get("modified").toString()); + + // close the
Summary
and
tags + out.write("
"); + } + else + { + out.write("Node could not be found in the repository!"); + } + } + + // ------------------------------------------------------------------------------ + // Bean getters and setters + + /** + * @param nodeService The NodeService to set. + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + public void setContentService(ContentService contentService) + { + this.contentService = contentService; + } + + // ------------------------------------------------------------------------------ + // Helper methods + + /** + * Writes a table row with the given data + * + * @param nameColumn The name of the data item + * @param dataColumn The data + */ + protected void writeRow(ResponseWriter out, String nameColumn, String dataColumn) + throws IOException + { + out.write(""); + } +} diff --git a/source/java/org/alfresco/web/bean/clipboard/ClipboardBean.java b/source/java/org/alfresco/web/bean/clipboard/ClipboardBean.java index 69048669df..7471bd3ba2 100644 --- a/source/java/org/alfresco/web/bean/clipboard/ClipboardBean.java +++ b/source/java/org/alfresco/web/bean/clipboard/ClipboardBean.java @@ -311,6 +311,13 @@ public class ClipboardBean dd.isSubClass(item.Node.getType(), ContentModel.TYPE_FOLDER)) { // copy the file/folder + // first check that we are not attempting to copy a duplicate into the same parent + if (destRef.equals(assocRef.getParentRef()) && name.equals(item.Node.getName())) + { + // manually change the name if this occurs + String copyOf = Application.getMessage(FacesContext.getCurrentInstance(), MSG_COPY_OF); + name = copyOf + ' ' + name; + } this.fileFolderService.copy( item.Node.getNodeRef(), destRef, diff --git a/source/java/org/alfresco/web/bean/content/AddContentDialog.java b/source/java/org/alfresco/web/bean/content/AddContentDialog.java index e3f6042431..dc18d4ce22 100644 --- a/source/java/org/alfresco/web/bean/content/AddContentDialog.java +++ b/source/java/org/alfresco/web/bean/content/AddContentDialog.java @@ -3,12 +3,17 @@ package org.alfresco.web.bean.content; import java.io.File; import java.io.Serializable; import java.text.MessageFormat; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; +import org.alfresco.config.Config; +import org.alfresco.config.ConfigElement; +import org.alfresco.config.ConfigService; import org.alfresco.model.ContentModel; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.filestore.FileContentReader; @@ -26,6 +31,7 @@ import org.alfresco.web.bean.repository.Repository; */ public class AddContentDialog extends BaseContentWizard { + protected List inlineEditableMimeTypes; protected File file; // ------------------------------------------------------------------------------ @@ -53,7 +59,16 @@ public class AddContentDialog extends BaseContentWizard { this.title = this.fileName; } - + + // determine whether inline editing should be enabled by default. + // if the mime type of the added file is in the list of mime types + // configured in "Content Wizards" then enable inline editing + List mimeTypes = getInlineEditableMimeTypes(); + if (mimeTypes.contains(this.mimeType)) + { + this.inlineEdit = true; + } + saveContent(this.file, null); // return default outcome @@ -71,6 +86,8 @@ public class AddContentDialog extends BaseContentWizard @Override protected String doPostCommitProcessing(FacesContext context, String outcome) { + clearUpload(); + // as we were successful, go to the set properties dialog if asked // to otherwise just return if (this.showOtherProperties) @@ -214,4 +231,30 @@ public class AddContentDialog extends BaseContentWizard FacesContext ctx = FacesContext.getCurrentInstance(); ctx.getExternalContext().getSessionMap().remove(FileUploadBean.FILE_UPLOAD_BEAN_NAME); } + + protected List getInlineEditableMimeTypes() + { + if (this.inlineEditableMimeTypes == null) + { + this.inlineEditableMimeTypes = new ArrayList(8); + + // get the create mime types list from the config + ConfigService svc = Application.getConfigService(FacesContext.getCurrentInstance()); + Config wizardCfg = svc.getConfig("Content Wizards"); + if (wizardCfg != null) + { + ConfigElement typesCfg = wizardCfg.getConfigElement("create-mime-types"); + if (typesCfg != null) + { + for (ConfigElement child : typesCfg.getChildren()) + { + String currentMimeType = child.getAttribute("name"); + this.inlineEditableMimeTypes.add(currentMimeType); + } + } + } + } + + return this.inlineEditableMimeTypes; + } } diff --git a/source/java/org/alfresco/web/bean/content/DeleteContentDialog.java b/source/java/org/alfresco/web/bean/content/DeleteContentDialog.java new file mode 100644 index 0000000000..1e48b2ea51 --- /dev/null +++ b/source/java/org/alfresco/web/bean/content/DeleteContentDialog.java @@ -0,0 +1,87 @@ +package org.alfresco.web.bean.content; + +import java.text.MessageFormat; + +import javax.faces.context.FacesContext; + +import org.alfresco.web.app.AlfrescoNavigationHandler; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.dialog.BaseDialogBean; +import org.alfresco.web.bean.repository.Node; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Bean implementation for the "Delete Content" dialog + * + * @author gavinc + */ +public class DeleteContentDialog extends BaseDialogBean +{ + private static final Log logger = LogFactory.getLog(DeleteContentDialog.class); + + // ------------------------------------------------------------------------------ + // Dialog implementation + + @Override + protected String finishImpl(FacesContext context, String outcome) + throws Exception + { + // get the content to delete + Node node = this.browseBean.getDocument(); + if (node != null) + { + if (logger.isDebugEnabled()) + logger.debug("Trying to delete content node: " + node.getId()); + + // delete the node + this.nodeService.deleteNode(node.getNodeRef()); + } + else + { + logger.warn("WARNING: delete called without a current Document!"); + } + + return outcome; + } + + @Override + protected String doPostCommitProcessing(FacesContext context, String outcome) + { + // clear action context + this.browseBean.setDocument(null); + + // setting the outcome will show the browse view again + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + + AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse"; + } + + @Override + protected String getErrorMessageId() + { + return "error_delete_file"; + } + + @Override + public boolean getFinishButtonDisabled() + { + return false; + } + + // ------------------------------------------------------------------------------ + // Bean Getters and Setters + + /** + * Returns the confirmation to display to the user before deleting the content. + * + * @return The formatted message to display + */ + public String getConfirmMessage() + { + String fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(), + "delete_file_confirm"); + + return MessageFormat.format(fileConfirmMsg, + new Object[] {this.browseBean.getDocument().getName()}); + } +} diff --git a/source/java/org/alfresco/web/bean/dashboard/DashboardManager.java b/source/java/org/alfresco/web/bean/dashboard/DashboardManager.java new file mode 100644 index 0000000000..bea7e5f967 --- /dev/null +++ b/source/java/org/alfresco/web/bean/dashboard/DashboardManager.java @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.web.bean.dashboard; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +import javax.faces.context.FacesContext; + +import org.alfresco.config.ConfigService; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.repository.PreferencesService; +import org.alfresco.web.config.DashboardsConfigElement; +import org.alfresco.web.config.DashboardsConfigElement.DashletDefinition; +import org.alfresco.web.config.DashboardsConfigElement.LayoutDefinition; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Bean that manages the Dashboard framework. + * + * @author Kevin Roast + */ +public class DashboardManager +{ + private static Log logger = LogFactory.getLog(DashboardManager.class); + + private static final String PREF_DASHBOARD = "dashboard"; + static final String LAYOUT_DEFAULT = "default"; + static final String DASHLET_DEFAULT = "getting-started"; + + private static final String JSP_DUMMY = "/jsp/dashboards/dummy.jsp"; + + private PageConfig pageConfig = null; + private DashletRenderingList renderingList = null; + private DashletTitleList titleList = null; + + /** + * @return The layout JSP page for the current My Alfresco dashboard page + */ + public String getLayoutPage() + { + String layout = null; + Page page = getPageConfig().getCurrentPage(); + if (page != null) + { + layout = page.getLayoutDefinition().JSPPage; + } + return layout; + } + + /** + * Helper to init the dashboard for display + */ + public void initDashboard() + { + this.renderingList = null; + this.titleList = null; + } + + /** + * @return JSF List getter to return which dashlets are available for rendering + */ + public List getDashletAvailable() + { + if (this.renderingList == null) + { + this.renderingList = new DashletRenderingList(getPageConfig()); + } + return this.renderingList; + } + + /** + * @return JSF List getter to return dashlet title strings + */ + public List getDashletTitle() + { + if (this.titleList == null) + { + this.titleList = new DashletTitleList(getPageConfig()); + } + return this.titleList; + } + + /** + * Return the JSP for the specified dashlet index + * + * @param index Zero based index from the left most column working top-bottom then left-right + * + * @return JSP page for the dashlet or a blank dummy page if not found + */ + public String getDashletPage(int index) + { + String page = JSP_DUMMY; + DashletDefinition def = getDashletDefinitionByIndex(getPageConfig(), index); + if (def != null) + { + page = def.JSPPage; + } + return page; + } + + /** + * @return the PageConfig for the current My Alfresco dashboard page + */ + public PageConfig getPageConfig() + { + if (this.pageConfig == null) + { + PageConfig pageConfig; + + DashboardsConfigElement config = getDashboardConfig(); + + // read the config for this user from the Preferences + String xml = (String)PreferencesService.getPreferences().getValue(PREF_DASHBOARD); + if (xml != null && xml.length() != 0) + { + if (logger.isDebugEnabled()) + logger.debug("PageConfig found: " + xml); + + // process the XML config and convert into a PageConfig object + pageConfig = new PageConfig(); + pageConfig.fromXML(config, xml); + } + else + { + if (logger.isDebugEnabled()) + logger.debug("No PageConfig found, creating default instance."); + + // create default config for the first access for a user + pageConfig = new PageConfig(); + LayoutDefinition layout = config.getLayoutDefinition(LAYOUT_DEFAULT); + if (layout != null) + { + Page page = new Page("default", layout); + Column defaultColumn = new Column(); + DashletDefinition dashlet = config.getDashletDefinition(DASHLET_DEFAULT); + if (dashlet != null) + { + defaultColumn.addDashlet(dashlet); + page.addColumn(defaultColumn); + pageConfig.addPage(page); + } + } + } + + this.pageConfig = pageConfig; + } + + return this.pageConfig; + } + + /** + * Persist the supplied PageConfig for the current user + */ + public void savePageConfig(PageConfig config) + { + this.pageConfig = config; + + // reset cached values + initDashboard(); + + // persist the changes + PreferencesService.getPreferences().setValue(PREF_DASHBOARD, this.pageConfig.toXML()); + } + + /** + * @return The externally configured WebClient config element for the Dashboards + */ + public static DashboardsConfigElement getDashboardConfig() + { + ConfigService service = Application.getConfigService(FacesContext.getCurrentInstance()); + DashboardsConfigElement config = (DashboardsConfigElement)service.getConfig("Dashboards").getConfigElement( + DashboardsConfigElement.CONFIG_ELEMENT_ID); + return config; + } + + /** + * Helper to get the DashDefinition as the zero based index, working from the left most column + * top-bottom then working left-right. + * + * @param index Zero based index from the left most column working top-bottom then left-right + * + * @return DashletDefinition if found or null if no dashlet at the specified index + */ + private static DashletDefinition getDashletDefinitionByIndex(PageConfig config, int index) + { + DashletDefinition def = null; + + LayoutDefinition layoutDef = config.getCurrentPage().getLayoutDefinition(); + List columns = config.getCurrentPage().getColumns(); + int columnCount = columns.size(); + int selectedColumn = index / layoutDef.ColumnLength; + if (selectedColumn < columnCount) + { + List dashlets = columns.get(selectedColumn).getDashlets(); + if (index % layoutDef.ColumnLength < dashlets.size()) + { + def = dashlets.get(index % layoutDef.ColumnLength); + } + } + if (logger.isDebugEnabled()) + logger.debug("Searching for dashlet at index: " + index + + " and found " + (def != null ? def.JSPPage : null)); + + return def; + } + + + /** + * Dashlet rendering list. + * + * Returns true from the get() method if the specified dashlet is available for rendering. + */ + private static class DashletRenderingList extends JSFHelperList + { + PageConfig config; + + public DashletRenderingList(PageConfig config) + { + this.config = config; + } + + /** + * @see java.util.List#get(int) + */ + public Object get(int index) + { + return getDashletDefinitionByIndex(config, index) != null; + } + } + + /** + * Dashlet title list. + * + * Returns the title string from the get() method if the specified dashlet is available. + */ + private static class DashletTitleList extends JSFHelperList + { + PageConfig config; + + public DashletTitleList(PageConfig config) + { + this.config = config; + } + + /** + * @see java.util.List#get(int) + */ + public Object get(int index) + { + String result = ""; + + DashletDefinition def = getDashletDefinitionByIndex(config, index); + if (def != null) + { + if (def.LabelId != null) + { + result = Application.getMessage(FacesContext.getCurrentInstance(), def.LabelId); + } + else if (def.Label != null) + { + result = def.Label; + } + } + + return result; + } + } + + /** + * Helper class that implements a dummy List contract for use by JSF List getter methods + */ + private static abstract class JSFHelperList implements List + { + // + // Satisfy List interface contract + // + + public void add(int arg0, Object arg1) + { + } + + public boolean add(Object arg0) + { + return false; + } + + public boolean addAll(Collection arg0) + { + return false; + } + + public boolean addAll(int arg0, Collection arg1) + { + return false; + } + + public void clear() + { + } + + public boolean contains(Object arg0) + { + return false; + } + + public boolean containsAll(Collection arg0) + { + return false; + } + + public int indexOf(Object arg0) + { + return 0; + } + + public boolean isEmpty() + { + return false; + } + + public Iterator iterator() + { + return null; + } + + public int lastIndexOf(Object arg0) + { + return 0; + } + + public ListIterator listIterator() + { + return null; + } + + public ListIterator listIterator(int arg0) + { + return null; + } + + public Object remove(int arg0) + { + return null; + } + + public boolean remove(Object arg0) + { + return false; + } + + public boolean removeAll(Collection arg0) + { + return false; + } + + public boolean retainAll(Collection arg0) + { + return false; + } + + public Object set(int arg0, Object arg1) + { + return null; + } + + public int size() + { + return 0; + } + + public List subList(int arg0, int arg1) + { + return null; + } + + public Object[] toArray() + { + return null; + } + + public Object[] toArray(Object[] arg0) + { + return null; + } + } +} diff --git a/source/java/org/alfresco/web/bean/dashboard/DashboardWizard.java b/source/java/org/alfresco/web/bean/dashboard/DashboardWizard.java new file mode 100644 index 0000000000..615570d480 --- /dev/null +++ b/source/java/org/alfresco/web/bean/dashboard/DashboardWizard.java @@ -0,0 +1,467 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.web.bean.dashboard; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.faces.component.UISelectMany; +import javax.faces.component.UISelectOne; +import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; +import javax.faces.model.SelectItem; + +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.wizard.BaseWizardBean; +import org.alfresco.web.config.DashboardsConfigElement; +import org.alfresco.web.config.DashboardsConfigElement.DashletDefinition; +import org.alfresco.web.config.DashboardsConfigElement.LayoutDefinition; +import org.alfresco.web.ui.common.component.UIListItem; +import org.alfresco.web.ui.common.component.description.UIDescription; + +/** + * @author Kevin Roast + */ +public class DashboardWizard extends BaseWizardBean +{ + private static final String COMPONENT_COLUMNDASHLETS = "column-dashlets"; + + private static final String COMPONENT_ALLDASHLETS = "all-dashlets"; + + private static final String MSG_COLUMN = "dashboard_column"; + + /** List of icons items to display as selectable Layout definitions */ + private List layoutIcons = null; + + /** List of descriptions of the layouts */ + private List layoutDescriptions = null; + + /** List of SelectItem objects representing the available dashlets */ + private List dashlets = null; + + /** Currently selected layout */ + private String layout; + + /** Currently selected column to edit */ + private int column; + + /** The PageConfig holding the columns/dashlets during editing */ + private PageConfig editConfig; + + /** The DashboardManager instance */ + private DashboardManager dashboardManager; + + + // ------------------------------------------------------------------------------ + // Bean setters + + /** + * @param dashboardManager The dashboardManager to set. + */ + public void setDashboardManager(DashboardManager dashboardManager) + { + this.dashboardManager = dashboardManager; + } + + + // ------------------------------------------------------------------------------ + // Wizard implementation + + /** + * @see org.alfresco.web.bean.dialog.BaseDialogBean#init(java.util.Map) + */ + public void init(Map parameters) + { + super.init(parameters); + + this.editConfig = new PageConfig(this.dashboardManager.getPageConfig()); + this.layout = this.editConfig.getCurrentPage().getLayoutDefinition().Id; + this.column = 0; + } + + /** + * @see org.alfresco.web.bean.dialog.BaseDialogBean#finishImpl(javax.faces.context.FacesContext, java.lang.String) + */ + protected String finishImpl(FacesContext context, String outcome) throws Exception + { + this.dashboardManager.savePageConfig(this.editConfig); + return outcome; + } + + /** + * @return Returns the summary data for the wizard. + */ + public String getSummary() + { + LayoutDefinition def = DashboardManager.getDashboardConfig().getLayoutDefinition(this.layout); + String label = def.Label; + if (label == null) + { + label = Application.getMessage(FacesContext.getCurrentInstance(), def.LabelId); + } + return buildSummary( + new String[]{"Layout"}, + new String[]{label}); + } + + + // ------------------------------------------------------------------------------ + // Dashboard Wizard bean getters + + /** + * @return The currently selected layout ID - used by the Dynamic Description component + */ + public String getLayout() + { + return this.layout; + } + + /** + * Set the currently selected layout ID + */ + public void setLayout(String layout) + { + this.layout = layout; + LayoutDefinition def = DashboardManager.getDashboardConfig().getLayoutDefinition(layout); + this.editConfig.getCurrentPage().setLayoutDefinition(def); + if (this.column >= def.Columns) + { + this.column = def.Columns - 1; + } + } + + /** + * @return the number of columns in the selected page layout + */ + public int getColumnCount() + { + return DashboardManager.getDashboardConfig().getLayoutDefinition(getLayout()).Columns; + } + + /** + * @return the number of components per column supported in the selected page layout + */ + public int getColumnMax() + { + return DashboardManager.getDashboardConfig().getLayoutDefinition(getLayout()).ColumnLength; + } + + /** + * @return the array of UI select items representing the columns that can be configured + */ + public SelectItem[] getColumns() + { + FacesContext fc = FacesContext.getCurrentInstance(); + LayoutDefinition layoutDef = DashboardManager.getDashboardConfig().getLayoutDefinition(getLayout()); + SelectItem[] columns = new SelectItem[layoutDef.Columns]; + for (int i=0; i getAllDashlets() + { + if (this.dashlets == null) + { + FacesContext fc = FacesContext.getCurrentInstance(); + DashboardsConfigElement config = DashboardManager.getDashboardConfig(); + Collection dashletDefs = config.getDashlets(); + List dashlets = new ArrayList(dashletDefs.size()); + for (DashletDefinition dashletDef : dashletDefs) + { + String label = dashletDef.Label; + if (label == null) + { + label = Application.getMessage(fc, dashletDef.LabelId); + } + String description = dashletDef.Description; + if (description == null) + { + description = Application.getMessage(fc, dashletDef.DescriptionId); + } + if (description != null) + { + // append description of the dashlet if set + label = label + " (" + description + ')'; + } + SelectItem item = new SelectItem(dashletDef.Id, label); + dashlets.add(item); + } + this.dashlets = dashlets; + } + return this.dashlets; + } + + /** + * @return the List of SelectItem objects representing the dashlets displayed in the + * currently selected column. + */ + public List getColumnDashlets() + { + FacesContext fc = FacesContext.getCurrentInstance(); + + Column column = this.editConfig.getCurrentPage().getColumns().get(this.column); + List dashlets = new ArrayList(column.getDashlets().size()); + for (DashletDefinition dashletDef : column.getDashlets()) + { + String label = dashletDef.Label; + if (label == null) + { + label = Application.getMessage(fc, dashletDef.LabelId); + } + dashlets.add(new SelectItem(dashletDef.Id, label)); + } + return dashlets; + } + + /** + * @return List of UIDescription objects for the available layouts + */ + public List getLayoutDescriptions() + { + if (this.layoutDescriptions == null) + { + buildLayoutValueLists(); + } + return this.layoutDescriptions; + } + + /** + * @return the List of UIListItem objects representing the Layout icons + */ + public List getLayoutIcons() + { + if (this.layoutIcons == null) + { + buildLayoutValueLists(); + } + return this.layoutIcons; + } + + /** + * Build the cached list of values for the layout page. The lists are used by the + * image radio picker and dynamic description components. + */ + private void buildLayoutValueLists() + { + List icons = new ArrayList(4); + List descriptions = new ArrayList(4); + + FacesContext context = FacesContext.getCurrentInstance(); + + DashboardsConfigElement config = DashboardManager.getDashboardConfig(); + Iterator layoutItr = config.getLayouts().iterator(); + while (layoutItr.hasNext()) + { + LayoutDefinition layoutDef = layoutItr.next(); + + // build UIListItem to represent the layout image + String label = layoutDef.Label; + if (label == null) + { + label = Application.getMessage(context, layoutDef.LabelId); + } + String desc = layoutDef.Description; + if (desc == null) + { + desc = Application.getMessage(context, layoutDef.DescriptionId); + } + UIListItem item = new UIListItem(); + item.setLabel(label); + item.setTooltip(desc); + item.setValue(layoutDef.Id); + // set the special attribute used by the imageRadioPicker component + item.getAttributes().put("image", layoutDef.Image); + icons.add(item); + + // build UIDescription to represent the layout description text + UIDescription description = new UIDescription(); + description.setControlValue(layoutDef.Id); + description.setText(desc); + descriptions.add(description); + } + + this.layoutIcons = icons; + this.layoutDescriptions = descriptions; + } + + /** + * Action event handler called to Add dashlets to the selection for a column + */ + public void addDashlets(ActionEvent event) + { + UISelectMany dashletPicker = (UISelectMany)event.getComponent().findComponent(COMPONENT_ALLDASHLETS); + UISelectOne dashletColumn = (UISelectOne)event.getComponent().findComponent(COMPONENT_COLUMNDASHLETS); + + // get the IDs of the selected Dashlet definitions + Object[] selected = dashletPicker.getSelectedValues(); + + if (selected.length != 0) + { + // get the column to add the dashlets too + DashboardsConfigElement config = DashboardManager.getDashboardConfig(); + LayoutDefinition layoutDef = this.editConfig.getCurrentPage().getLayoutDefinition(); + Column column = this.editConfig.getCurrentPage().getColumns().get(this.column); + + // add each selected dashlet to the column + for (int i=0; i pages = new ArrayList(4); + private int currentPageIndex = 0; + + + /** + * Default constructor + */ + public PageConfig() + { + } + + /** + * Copy constructor + * + * @param copy PageConfig to copy + */ + public PageConfig(PageConfig copy) + { + this.pages = new ArrayList(copy.pages.size()); + for (Page page : copy.pages) + { + // invoke the copy constructor on each Page + // which in turn calls the copy constructor of child classes + this.pages.add(new Page(page)); + } + } + + /** + * @return The current page in the config + */ + public Page getCurrentPage() + { + if (currentPageIndex < pages.size()) + { + return pages.get(currentPageIndex); + } + else + { + return null; + } + } + + /** + * Add a new Page to the list + * + * @param page Page to add + */ + public void addPage(Page page) + { + pages.add(page); + } + + /** + * Get a Page with the specified page Id + * + * @param pageId Of the page to return + * + * @return Page or null if not found + */ + public Page getPage(String pageId) + { + Page foundPage = null; + for (Page page : pages) + { + if (page.getId().equals(pageId)) + { + foundPage = page; + break; + } + } + return foundPage; + } + + /** + * Convert this config to an XML definition which can be serialized. + * Example: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * @return XML for this config + */ + public String toXML() + { + try + { + Document doc = DocumentHelper.createDocument(); + + Element root = doc.addElement(ELEMENT_DASHBOARD); + for (Page page : pages) + { + Element pageElement = root.addElement(ELEMENT_PAGE); + pageElement.addAttribute(ATTR_ID, page.getId()); + pageElement.addAttribute(ATTR_LAYOUTID, page.getLayoutDefinition().Id); + for (Column column : page.getColumns()) + { + Element columnElement = pageElement.addElement(ELEMENT_COLUMN); + for (DashletDefinition dashletDef : column.getDashlets()) + { + columnElement.addElement(ELEMENT_DASHLET).addAttribute(ATTR_REFID, dashletDef.Id); + } + } + } + + StringWriter out = new StringWriter(512); + XMLWriter writer = new XMLWriter(OutputFormat.createPrettyPrint()); + writer.setWriter(out); + writer.write(doc); + + return out.toString(); + } + catch (Throwable err) + { + throw new AlfrescoRuntimeException("Unable to serialize Dashboard PageConfig to XML: " + err.getMessage(), err); + } + } + + @Override + public String toString() + { + return toXML(); + } + + /** + * Deserialise this PageConfig instance from the specified XML stream. + * + * @param xml + */ + public void fromXML(DashboardsConfigElement config, String xml) + { + try + { + SAXReader reader = new SAXReader(); + Document document = reader.read(new StringReader(xml)); + Element rootElement = document.getRootElement(); + + // walk the pages found in xml + Iterator itrPages = rootElement.elementIterator(ELEMENT_PAGE); + while (itrPages.hasNext()) + { + Element pageElement = (Element)itrPages.next(); + String layoutId = pageElement.attributeValue(ATTR_LAYOUTID); + LayoutDefinition layoutDef = config.getLayoutDefinition(layoutId); + if (layoutDef != null) + { + // found the layout now build the page and read the columns + Page page = new Page(pageElement.attributeValue(ATTR_ID), layoutDef); + Iterator itrColumns = pageElement.elementIterator(ELEMENT_COLUMN); + while (itrColumns.hasNext()) + { + Column column = new Column(); + + // read and resolve the dashlet definitions for this column + Element columnElement = (Element)itrColumns.next(); + Iterator itrDashlets = columnElement.elementIterator(ELEMENT_DASHLET); + while (itrDashlets.hasNext()) + { + String dashletId = ((Element)itrDashlets.next()).attributeValue(ATTR_REFID); + DashletDefinition dashletDef = config.getDashletDefinition(dashletId); + if (dashletDef != null) + { + column.addDashlet(dashletDef); + } + else if (logger.isWarnEnabled()) + { + logger.warn("Failed to resolve Dashboard Dashlet Definition ID: " + dashletId); + } + } + + // add the column of dashlets to the page + page.addColumn(column); + } + + // add the page to this config instance + this.addPage(page); + } + else if (logger.isWarnEnabled()) + { + logger.warn("Failed to resolve Dashboard Layout Definition ID: " + layoutId); + } + } + } + catch (DocumentException docErr) + { + // if we cannot parse, then we simply revert to default + } + } +} + +/** + * Simple class to represent a Page in a Dashboard. + * Each Page has a Layout associated with it, and a number of Column definitions. + */ +final class Page +{ + private String id; + private LayoutDefinition layoutDef; + private List columns = new ArrayList(4); + + /** + * Constructor + * + * @param id + * @param layout + */ + public Page(String id, LayoutDefinition layout) + { + if (id == null || id.length() == 0) + { + throw new IllegalArgumentException("ID for a Dashboard Page is mandatory."); + } + if (layout == null) + { + throw new IllegalArgumentException("Layout for a Dashboard Page is mandatory."); + } + this.id = id; + this.layoutDef = layout; + } + + /** + * Copy Constructor + * + * @param copy Page to build a copy from + */ + public Page(Page copy) + { + this.id = copy.id; + this.layoutDef = copy.layoutDef; + for (Column column : copy.columns) + { + Column cloneColumn = new Column(column); + addColumn(cloneColumn); + } + } + + public String getId() + { + return this.id; + } + + public LayoutDefinition getLayoutDefinition() + { + return this.layoutDef; + } + + public void setLayoutDefinition(LayoutDefinition layout) + { + if (layout == null) + { + throw new IllegalArgumentException("Layout for a Dashboard Page is mandatory."); + } + + // correct column collection based on new layout definition + while (this.columns.size() < layout.Columns) + { + addColumn(new Column()); + } + if (this.columns.size() > layout.Columns) + { + this.columns = this.columns.subList(0, layout.Columns); + } + + this.layoutDef = layout; + } + + public void addColumn(Column column) + { + this.columns.add(column); + } + + public List getColumns() + { + return this.columns; + } +} + +/** + * Simple class representing a single Column in a dashboard Page. + * Each column contains a list of Dashlet definitions. + */ +final class Column +{ + private List dashlets = new ArrayList(4); + + /** + * Default constructor + */ + public Column() + { + } + + /** + * Copy constructor + * + * @param copy Column to copy + */ + public Column(Column copy) + { + this.dashlets = (List)((ArrayList)copy.dashlets).clone(); + } + + public void addDashlet(DashletDefinition dashlet) + { + dashlets.add(dashlet); + } + + public List getDashlets() + { + return this.dashlets; + } +} diff --git a/source/java/org/alfresco/web/bean/forums/CreateDiscussionDialog.java b/source/java/org/alfresco/web/bean/forums/CreateDiscussionDialog.java index 8d42b33b30..6bf649df91 100644 --- a/source/java/org/alfresco/web/bean/forums/CreateDiscussionDialog.java +++ b/source/java/org/alfresco/web/bean/forums/CreateDiscussionDialog.java @@ -16,6 +16,7 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; import org.alfresco.web.app.AlfrescoNavigationHandler; import org.alfresco.web.app.Application; +import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.ui.common.Utils; import org.apache.commons.logging.Log; @@ -154,11 +155,17 @@ public class CreateDiscussionDialog extends CreateTopicDialog this.nodeService.removeAspect(this.discussingNodeRef, ForumModel.ASPECT_DISCUSSABLE); // delete the forum space created when the wizard started - this.browseBean.setActionSpace(this.navigator.getCurrentNode()); - this.browseBean.deleteSpaceOK(); - + Node forumNode = this.navigator.getCurrentNode(); + this.nodeService.deleteNode(forumNode.getNodeRef()); + // commit the transaction tx.commit(); + + // remove this node from the breadcrumb if required + this.browseBean.removeSpaceFromBreadcrumb(forumNode); + + // clear action context + this.browseBean.setActionSpace(null); } catch (Throwable e) { diff --git a/source/java/org/alfresco/web/bean/forums/CreateReplyDialog.java b/source/java/org/alfresco/web/bean/forums/CreateReplyDialog.java index 6eb6c0c471..2602445122 100644 --- a/source/java/org/alfresco/web/bean/forums/CreateReplyDialog.java +++ b/source/java/org/alfresco/web/bean/forums/CreateReplyDialog.java @@ -5,8 +5,6 @@ import java.util.Map; import javax.faces.context.FacesContext; import org.alfresco.model.ContentModel; -import org.alfresco.service.cmr.repository.ContentReader; -import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.web.app.Application; import org.alfresco.web.ui.common.Utils; import org.apache.commons.logging.Log; @@ -62,32 +60,4 @@ public class CreateReplyDialog extends CreatePostDialog { return Application.getMessage(FacesContext.getCurrentInstance(), "reply"); } - - // ------------------------------------------------------------------------------ - // Bean Getters and Setters - - /** - * Returns the content of the post we are replying to - * - * @return The content - */ - public String getReplyContent() - { - if (this.replyContent == null) - { - // get the content reader of the node we are replying to - NodeRef replyNode = this.browseBean.getDocument().getNodeRef(); - if (replyNode != null) - { - ContentReader reader = this.contentService.getReader(replyNode, ContentModel.PROP_CONTENT); - - if (reader != null) - { - this.replyContent = reader.getContentString(); - } - } - } - - return this.replyContent; - } } diff --git a/source/java/org/alfresco/web/bean/forums/DeleteForumDialog.java b/source/java/org/alfresco/web/bean/forums/DeleteForumDialog.java new file mode 100644 index 0000000000..786511cbf8 --- /dev/null +++ b/source/java/org/alfresco/web/bean/forums/DeleteForumDialog.java @@ -0,0 +1,103 @@ +package org.alfresco.web.bean.forums; + +import java.text.MessageFormat; +import java.util.Map; + +import javax.faces.context.FacesContext; + +import org.alfresco.model.ForumModel; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.alfresco.web.app.AlfrescoNavigationHandler; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.repository.Node; +import org.alfresco.web.bean.spaces.DeleteSpaceDialog; + +/** + * Bean implementation for the "Delete Forum" dialog + * + * @author gavinc + */ +public class DeleteForumDialog extends DeleteSpaceDialog +{ + protected boolean reDisplayForums; + + // ------------------------------------------------------------------------------ + // Dialog implementation + + @Override + public void init(Map parameters) + { + super.init(parameters); + + // reset the reDisplayForums flag + this.reDisplayForums = false; + } + + @Override + protected String finishImpl(FacesContext context, String outcome) throws Exception + { + // find out what the parent type of the node being deleted + Node node = this.browseBean.getActionSpace(); + ChildAssociationRef assoc = this.nodeService.getPrimaryParent(node.getNodeRef()); + if (assoc != null) + { + // get the parent node + NodeRef parent = assoc.getParentRef(); + + // get the association type + QName type = assoc.getTypeQName(); + if (type.equals(ForumModel.ASSOC_DISCUSSION)) + { + // if the association type is the 'discussion' association we + // need to remove the discussable aspect from the parent node + this.nodeService.removeAspect(parent, ForumModel.ASPECT_DISCUSSABLE); + } + + // if the parent type is a forum space then we need the dialog to go + // back to the forums view otherwise it will use the default of 'browse', + // this happens when a forum being used to discuss a node is deleted. + QName parentType = this.nodeService.getType(parent); + if (parentType.equals(ForumModel.TYPE_FORUMS)) + { + this.reDisplayForums = true; + } + } + + return super.finishImpl(context, outcome); + } + + @Override + protected String doPostCommitProcessing(FacesContext context, String outcome) + { + outcome = super.doPostCommitProcessing(context, outcome); + + if (this.reDisplayForums) + { + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + + AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "forumDeleted"; + } + else + { + return outcome; + } + } + + // ------------------------------------------------------------------------------ + // Bean Getters and Setters + + /** + * Returns the confirmation to display to the user before deleting the content. + * + * @return The formatted message to display + */ + public String getConfirmMessage() + { + String fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(), + "delete_forum_confirm"); + + return MessageFormat.format(fileConfirmMsg, + new Object[] {this.browseBean.getActionSpace().getName()}); + } +} diff --git a/source/java/org/alfresco/web/bean/forums/DeleteForumsDialog.java b/source/java/org/alfresco/web/bean/forums/DeleteForumsDialog.java new file mode 100644 index 0000000000..a8902db9ee --- /dev/null +++ b/source/java/org/alfresco/web/bean/forums/DeleteForumsDialog.java @@ -0,0 +1,70 @@ +package org.alfresco.web.bean.forums; + +import java.util.Map; + +import javax.faces.context.FacesContext; + +import org.alfresco.model.ForumModel; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.alfresco.web.app.AlfrescoNavigationHandler; +import org.alfresco.web.bean.repository.Node; +import org.alfresco.web.bean.spaces.DeleteSpaceDialog; + +/** + * Bean implementation for the "Delete Forum Space" dialog + * + * @author gavinc + */ +public class DeleteForumsDialog extends DeleteSpaceDialog +{ + protected boolean reDisplayForums; + + // ------------------------------------------------------------------------------ + // Dialog implementation + + @Override + public void init(Map parameters) + { + super.init(parameters); + + // reset the reDisplayForums flag + this.reDisplayForums = false; + } + + @Override + protected String finishImpl(FacesContext context, String outcome) throws Exception + { + // find out what the parent type of the node being deleted + Node node = this.browseBean.getActionSpace(); + ChildAssociationRef assoc = this.nodeService.getPrimaryParent(node.getNodeRef()); + if (assoc != null) + { + NodeRef parent = assoc.getParentRef(); + QName parentType = this.nodeService.getType(parent); + if (parentType.equals(ForumModel.TYPE_FORUMS)) + { + this.reDisplayForums = true; + } + } + + return super.finishImpl(context, outcome); + } + + @Override + protected String doPostCommitProcessing(FacesContext context, String outcome) + { + outcome = super.doPostCommitProcessing(context, outcome); + + if (this.reDisplayForums) + { + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + + AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "forumsDeleted"; + } + else + { + return outcome; + } + } +} diff --git a/source/java/org/alfresco/web/bean/forums/DeletePostDialog.java b/source/java/org/alfresco/web/bean/forums/DeletePostDialog.java new file mode 100644 index 0000000000..eded89c149 --- /dev/null +++ b/source/java/org/alfresco/web/bean/forums/DeletePostDialog.java @@ -0,0 +1,44 @@ +package org.alfresco.web.bean.forums; + +import java.text.MessageFormat; + +import javax.faces.context.FacesContext; + +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.content.DeleteContentDialog; + +/** + * Bean implementation for the "Delete Post" dialog. + * + * @author gavinc + */ +public class DeletePostDialog extends DeleteContentDialog +{ + // ------------------------------------------------------------------------------ + // Dialog implementation + + @Override + protected String doPostCommitProcessing(FacesContext context, String outcome) + { + super.doPostCommitProcessing(context, outcome); + + return this.getDefaultFinishOutcome(); + } + + // ------------------------------------------------------------------------------ + // Bean Getters and Setters + + /** + * Returns the confirmation to display to the user before deleting the content. + * + * @return The formatted message to display + */ + public String getConfirmMessage() + { + String postConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(), + "delete_post_confirm"); + + return MessageFormat.format(postConfirmMsg, + new Object[] {this.browseBean.getDocument().getProperties().get("creator")}); + } +} diff --git a/source/java/org/alfresco/web/bean/forums/DeleteTopicDialog.java b/source/java/org/alfresco/web/bean/forums/DeleteTopicDialog.java new file mode 100644 index 0000000000..fcb2c93869 --- /dev/null +++ b/source/java/org/alfresco/web/bean/forums/DeleteTopicDialog.java @@ -0,0 +1,89 @@ +package org.alfresco.web.bean.forums; + +import java.text.MessageFormat; +import java.util.Map; + +import javax.faces.context.FacesContext; + +import org.alfresco.model.ForumModel; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.alfresco.web.app.AlfrescoNavigationHandler; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.repository.Node; +import org.alfresco.web.bean.spaces.DeleteSpaceDialog; + +/** + * Bean implementation for the "Delete Topic" dialog + * + * @author gavinc + */ +public class DeleteTopicDialog extends DeleteSpaceDialog +{ + protected boolean reDisplayTopics; + + // ------------------------------------------------------------------------------ + // Dialog implementation + + @Override + public void init(Map parameters) + { + super.init(parameters); + + // reset the reDisplayTopics flag + this.reDisplayTopics = false; + } + + @Override + protected String finishImpl(FacesContext context, String outcome) throws Exception + { + // find out what the parent type of the node being deleted + Node node = this.browseBean.getActionSpace(); + ChildAssociationRef assoc = this.nodeService.getPrimaryParent(node.getNodeRef()); + if (assoc != null) + { + NodeRef parent = assoc.getParentRef(); + QName parentType = this.nodeService.getType(parent); + if (parentType.equals(ForumModel.TYPE_FORUM)) + { + this.reDisplayTopics = true; + } + } + + return super.finishImpl(context, outcome); + } + + @Override + protected String doPostCommitProcessing(FacesContext context, String outcome) + { + outcome = super.doPostCommitProcessing(context, outcome); + + if (this.reDisplayTopics) + { + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + + AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "topicDeleted"; + } + else + { + return outcome; + } + } + + // ------------------------------------------------------------------------------ + // Bean Getters and Setters + + /** + * Returns the confirmation to display to the user before deleting the content. + * + * @return The formatted message to display + */ + public String getConfirmMessage() + { + String fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(), + "delete_topic_confirm"); + + return MessageFormat.format(fileConfirmMsg, + new Object[] {this.browseBean.getActionSpace().getName()}); + } +} diff --git a/source/java/org/alfresco/web/bean/forums/ForumsBean.java b/source/java/org/alfresco/web/bean/forums/ForumsBean.java index 3e93b12cbf..81d016fd86 100644 --- a/source/java/org/alfresco/web/bean/forums/ForumsBean.java +++ b/source/java/org/alfresco/web/bean/forums/ForumsBean.java @@ -17,6 +17,7 @@ package org.alfresco.web.bean.forums; import java.io.IOException; +import java.io.StringWriter; import java.io.Writer; import java.text.MessageFormat; import java.text.SimpleDateFormat; @@ -50,7 +51,6 @@ import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; -import org.alfresco.web.app.AlfrescoNavigationHandler; import org.alfresco.web.app.Application; import org.alfresco.web.app.context.IContextListener; import org.alfresco.web.app.context.UIContextService; @@ -536,6 +536,61 @@ public class ForumsBean implements IContextListener } } + /** + * Returns the HTML to represent a bubble rendition of the text of the the + * forum article being replied to. + * + * @return The HTML for the bubble + */ + public String getReplyBubbleHTML() + { + try + { + // if the forum being replied to was a new post show the orange bubble + // with the user on the left otherwise show the yellow bubble with the + // user on the right. + StringWriter writer = new StringWriter(); + + FacesContext context = FacesContext.getCurrentInstance(); + Node replyToNode = this.browseBean.getDocument(); + boolean isReplyPost = this.nodeService.hasAspect(replyToNode.getNodeRef(), + ContentModel.ASPECT_REFERENCING); + String contextPath = context.getExternalContext().getRequestContextPath(); + String colour = isReplyPost ? "yellow" : "orange"; + String bgColour = isReplyPost ? "#FFF5A3" : "#FCC75E"; + + // build the HTML to represent the user that posted the article being replied to + StringBuilder replyPosterHTML = new StringBuilder(""); + + // start the table + writer.write("
"); + out.write(nameColumn); + out.write(""); + if (dataColumn != null) + { + out.write(dataColumn); + } + else + { + out.write(" "); + } + out.write("
"); + replyPosterHTML.append("
"); + replyPosterHTML.append((String)replyToNode.getProperties().get("creator")); + replyPosterHTML.append("
"); + + if (isReplyPost) + { + renderReplyContentHTML(context, replyToNode, writer, contextPath, colour, bgColour); + writer.write(replyPosterHTML.toString()); + } + else + { + writer.write(replyPosterHTML.toString()); + renderReplyContentHTML(context, replyToNode, writer, contextPath, colour, bgColour); + } + + // finish the table + writer.write("
"); + + return writer.toString(); + } + catch (IOException ioe) + { + throw new AlfrescoRuntimeException("Failed to render reply bubble HTML", ioe); + } + } // ------------------------------------------------------------------------------ // IContextListener implementation @@ -697,159 +752,21 @@ public class ForumsBean implements IContextListener ForumModel.ASSOC_DISCUSSION, RegexQNamePattern.MATCH_ALL); // there should only be one child, retrieve it if there is - if (children.size() != 1) + if (children.size() == 1) { - throw new IllegalStateException("Node has the discussable aspect but does not have 1 child, it has " + - children.size() + " children!"); + // show the forum for the discussion + NodeRef forumNodeRef = children.get(0).getChildRef(); + this.browseBean.clickSpace(forumNodeRef); + context.getApplication().getNavigationHandler().handleNavigation(context, null, "showForum"); + } + else + { + // this should never happen as the action evaluator should stop the action + // from displaying, just in case print a warning to the console + logger.warn("Node has the discussable aspect but does not have 1 child, it has " + + children.size() + " children!"); } - - // show the forum for the discussion - NodeRef forumNodeRef = children.get(0).getChildRef(); - this.browseBean.clickSpace(forumNodeRef); - context.getApplication().getNavigationHandler().handleNavigation(context, null, "showForum"); } - - /** - * Called when the user confirms they wish to delete a forum space - * - * @return The outcome - */ - public String deleteForumsOK() - { - String outcomeOverride = "browse"; - - // find out what the parent type of the node being deleted - Node node = this.browseBean.getActionSpace(); - ChildAssociationRef assoc = this.nodeService.getPrimaryParent(node.getNodeRef()); - if (assoc != null) - { - NodeRef parent = assoc.getParentRef(); - QName parentType = this.nodeService.getType(parent); - if (parentType.equals(ForumModel.TYPE_FORUMS)) - { - outcomeOverride = "forumsDeleted"; - } - } - - // call the generic handler - String outcome = this.browseBean.deleteSpaceOK(); - - // if the delete was successful update the outcome - if (outcome != null) - { - // return an overidden outcome which closes the dialog with an outcome - outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + - AlfrescoNavigationHandler.OUTCOME_SEPARATOR + outcomeOverride; - } - - return outcome; - } - - /** - * Called when the user confirms they wish to delete a forum space - * - * @return The outcome - */ - public String deleteForumOK() - { - String outcomeOverride = "browse"; - - // if this forum is being used for a discussion on a node we also - // need to remove the discussable aspect from the node. - Node forumSpace = this.browseBean.getActionSpace(); - ChildAssociationRef assoc = this.nodeService.getPrimaryParent(forumSpace.getNodeRef()); - if (assoc != null) - { - // get the parent node - NodeRef parent = assoc.getParentRef(); - - // get the association type - QName type = assoc.getTypeQName(); - if (type.equals(ForumModel.ASSOC_DISCUSSION)) - { - // if the association type is the 'discussion' association we - // need to remove the discussable aspect from the parent node - this.nodeService.removeAspect(parent, ForumModel.ASPECT_DISCUSSABLE); - } - - // if the parent type is a forum space then we need the dialog to go - // back to the forums view otherwise it will use the default of 'browse', - // this happens when a forum being used to discuss a node is deleted. - QName parentType = this.nodeService.getType(parent); - if (parentType.equals(ForumModel.TYPE_FORUMS)) - { - outcomeOverride = "forumDeleted"; - } - } - - // call the generic handler - String outcome = this.browseBean.deleteSpaceOK(); - - // if the delete was successful update the outcome - if (outcome != null) - { - // return an overidden outcome which closes the dialog with an outcome - outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + - AlfrescoNavigationHandler.OUTCOME_SEPARATOR + outcomeOverride; - } - - return outcome; - } - - /** - * Called when the user confirms they wish to delete a forum space - * - * @return The outcome - */ - public String deleteTopicOK() - { - String outcomeOverride = "browse"; - - // find out what the parent type of the node being deleted - Node node = this.browseBean.getActionSpace(); - ChildAssociationRef assoc = this.nodeService.getPrimaryParent(node.getNodeRef()); - if (assoc != null) - { - NodeRef parent = assoc.getParentRef(); - QName parentType = this.nodeService.getType(parent); - if (parentType.equals(ForumModel.TYPE_FORUM)) - { - outcomeOverride = "topicDeleted"; - } - } - - // call the generic handler - String outcome = this.browseBean.deleteSpaceOK(); - - // if the delete was successful update the outcome - if (outcome != null) - { - outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + - AlfrescoNavigationHandler.OUTCOME_SEPARATOR + outcomeOverride; - } - - return outcome; - } - - /** - * Called when the user confirms they wish to delete a forum space - * - * @return The outcome - */ - public String deletePostOK() - { - // call the generic handler - String outcome = this.browseBean.deleteFileOK(); - - // if the delete was successful update the outcome - if (outcome != null) - { - outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; - } - - return outcome; - } - // ------------------------------------------------------------------------------ // Property Resolvers @@ -943,7 +860,7 @@ public class ForumsBean implements IContextListener // ------------------------------------------------------------------------------ - // Private helpers + // Helpers /** * Initialise default values from client configuration @@ -980,6 +897,37 @@ public class ForumsBean implements IContextListener } } + protected void renderReplyContentHTML(FacesContext context, + Node replyToNode, StringWriter writer, + String contextPath, String colour, String bgColour) + throws IOException + { + // get the content of the article being replied to + String replyContent = ""; + ContentReader reader = this.contentService.getReader(replyToNode.getNodeRef(), + ContentModel.PROP_CONTENT); + if (reader != null) + { + replyContent = reader.getContentString(); + } + + // get the date of the article being replied to + String postedDate = Utils.getDateTimeFormat(context). + format(replyToNode.getProperties().get("created")); + + // generate the HTML + writer.write(""); + TopicBubbleViewRenderer.renderBubbleTop(writer, contextPath, colour, bgColour); + writer.write(""); + writer.write(Application.getMessage(context, "posted")); + writer.write(": "); + writer.write(postedDate); + TopicBubbleViewRenderer.renderBubbleMiddle(writer, contextPath, colour); + writer.write(replyContent); + TopicBubbleViewRenderer.renderBubbleBottom(writer, contextPath, colour); + writer.write(""); + } + /** * Class to implement a bubble view for the RichList component used in the topics screen * diff --git a/source/java/org/alfresco/web/bean/repository/DataDictionary.java b/source/java/org/alfresco/web/bean/repository/DataDictionary.java index 3d3927e19e..dd92c04593 100644 --- a/source/java/org/alfresco/web/bean/repository/DataDictionary.java +++ b/source/java/org/alfresco/web/bean/repository/DataDictionary.java @@ -24,10 +24,7 @@ import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.dictionary.TypeDefinition; -import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; /** * Lighweight client side representation of the repository data dictionary. @@ -38,9 +35,7 @@ import org.apache.commons.logging.LogFactory; */ public final class DataDictionary { - private static Log logger = LogFactory.getLog(DataDictionary.class); private DictionaryService dictionaryService; - private NamespaceService namespaceService; private Map types = new HashMap(11, 1.0f); /** diff --git a/source/java/org/alfresco/web/bean/repository/Node.java b/source/java/org/alfresco/web/bean/repository/Node.java index 237b2e6ca2..f0a6e49e12 100644 --- a/source/java/org/alfresco/web/bean/repository/Node.java +++ b/source/java/org/alfresco/web/bean/repository/Node.java @@ -48,7 +48,7 @@ public class Node implements Serializable { private static final long serialVersionUID = 3544390322739034169L; - protected static Log logger = LogFactory.getLog(Node.class); + protected static final Log logger = LogFactory.getLog(Node.class); protected NodeRef nodeRef; private String name; diff --git a/source/java/org/alfresco/web/bean/repository/Preferences.java b/source/java/org/alfresco/web/bean/repository/Preferences.java new file mode 100644 index 0000000000..71ad18778e --- /dev/null +++ b/source/java/org/alfresco/web/bean/repository/Preferences.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.web.bean.repository; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import javax.faces.context.FacesContext; + +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; + +/** + * Wraps the notion of preferences and settings for a User. + * Caches values until they are overwritten with a new value. + * + * @author Kevin Roast + */ +public final class Preferences +{ + private NodeRef preferencesRef; + private NodeService nodeService; + private Map cache = new HashMap(16, 1.0f); + + /** + * Package level constructor + */ + Preferences(NodeRef prefRef) + { + if (prefRef == null) + { + throw new IllegalArgumentException("Preferences NodeRef cannot be null."); + } + this.preferencesRef = prefRef; + } + + /** + * Get a serialized preferences value. + * + * @param name Name of the value to retrieve. + * + * @return The value or null if not found/set. + */ + public Serializable getValue(String name) + { + Serializable value = this.cache.get(name); + if (value == null) + { + QName qname = QName.createQName(NamespaceService.APP_MODEL_1_0_URI, name); + value = getNodeService().getProperty(this.preferencesRef, qname); + this.cache.put(name, value); + } + return value; + } + + /** + * Set a serialized preference value. + * + * @param name Name of the value to set. + * @param value Value to set. + */ + public void setValue(String name, Serializable value) + { + QName qname = QName.createQName(NamespaceService.APP_MODEL_1_0_URI, name); + // persist the property to the repo + getNodeService().setProperty(this.preferencesRef, qname, value); + // update the cache + this.cache.put(name, value); + } + + /** + * @return the NodeService instance. + */ + private NodeService getNodeService() + { + if (this.nodeService == null) + { + this.nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService(); + } + return this.nodeService; + } +} diff --git a/source/java/org/alfresco/web/bean/repository/PreferencesService.java b/source/java/org/alfresco/web/bean/repository/PreferencesService.java new file mode 100644 index 0000000000..84796a9bd9 --- /dev/null +++ b/source/java/org/alfresco/web/bean/repository/PreferencesService.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.web.bean.repository; + +import javax.faces.context.FacesContext; + +import org.alfresco.web.app.Application; + +/** + * Simple client service to retrieve the Preferences object for the current User. + * + * @author Kevin Roast + */ +public final class PreferencesService +{ + /** + * Private constructor + */ + private PreferencesService() + { + } + + /** + * @return The Preferences for the current User instance. + */ + public static Preferences getPreferences() + { + return getPreferences(FacesContext.getCurrentInstance()); + } + + /** + * @param fc FacesContext + * @return The Preferences for the current User instance. + */ + public static Preferences getPreferences(FacesContext fc) + { + User user = Application.getCurrentUser(fc); + return getPreferences(user); + } + + /** + * @param user User instance + * @return The Preferences for the current User instance. + */ + public static Preferences getPreferences(User user) + { + return user.getPreferences(); + } +} diff --git a/source/java/org/alfresco/web/bean/repository/User.java b/source/java/org/alfresco/web/bean/repository/User.java index c6f794649c..cfcb58a2bb 100644 --- a/source/java/org/alfresco/web/bean/repository/User.java +++ b/source/java/org/alfresco/web/bean/repository/User.java @@ -45,8 +45,7 @@ public final class User private String fullName = null; private Boolean administrator = null; - /** cached ref to our user preferences node */ - private NodeRef preferencesFolderRef = null; + private Preferences preferences = null; /** * Constructor @@ -139,63 +138,70 @@ public final class User return administrator; } + /** + * @return The Preferences for the User + */ + Preferences getPreferences() + { + if (this.preferences == null) + { + this.preferences = new Preferences(getUserPreferencesRef()); + } + return this.preferences; + } + /** * Get or create the node used to store user preferences. * Utilises the 'configurable' aspect on the Person linked to this user. */ - public synchronized NodeRef getUserPreferencesRef() + synchronized NodeRef getUserPreferencesRef() { - if (this.preferencesFolderRef == null) + FacesContext fc = FacesContext.getCurrentInstance(); + ServiceRegistry registry = Repository.getServiceRegistry(fc); + NodeService nodeService = registry.getNodeService(); + SearchService searchService = registry.getSearchService(); + NamespaceService namespaceService = registry.getNamespaceService(); + ConfigurableService configurableService = Repository.getConfigurableService(fc); + + NodeRef person = Application.getCurrentUser(fc).getPerson(); + if (nodeService.hasAspect(person, ContentModel.ASPECT_CONFIGURABLE) == false) { - FacesContext fc = FacesContext.getCurrentInstance(); - ServiceRegistry registry = Repository.getServiceRegistry(fc); - NodeService nodeService = registry.getNodeService(); - SearchService searchService = registry.getSearchService(); - NamespaceService namespaceService = registry.getNamespaceService(); - ConfigurableService configurableService = Repository.getConfigurableService(fc); - - NodeRef person = Application.getCurrentUser(fc).getPerson(); - if (nodeService.hasAspect(person, ContentModel.ASPECT_CONFIGURABLE) == false) - { - // create the configuration folder for this Person node - configurableService.makeConfigurable(person); - } - - // target of the assoc is the configurations folder ref - NodeRef configRef = configurableService.getConfigurationFolder(person); - if (configRef == null) - { - throw new IllegalStateException("Unable to find associated 'configurations' folder for node: " + person); - } - - String xpath = NamespaceService.APP_MODEL_PREFIX + ":" + "preferences"; - List nodes = searchService.selectNodes( - configRef, - xpath, - null, - namespaceService, - false); - - NodeRef prefRef; - if (nodes.size() == 1) - { - prefRef = nodes.get(0); - } - else - { - // create the preferences Node for this user - ChildAssociationRef childRef = nodeService.createNode( - configRef, - ContentModel.ASSOC_CONTAINS, - QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "preferences"), - ContentModel.TYPE_CMOBJECT); - - prefRef = childRef.getChildRef(); - } - - this.preferencesFolderRef = prefRef; + // create the configuration folder for this Person node + configurableService.makeConfigurable(person); } - return this.preferencesFolderRef; + // target of the assoc is the configurations folder ref + NodeRef configRef = configurableService.getConfigurationFolder(person); + if (configRef == null) + { + throw new IllegalStateException("Unable to find associated 'configurations' folder for node: " + person); + } + + String xpath = NamespaceService.APP_MODEL_PREFIX + ":" + "preferences"; + List nodes = searchService.selectNodes( + configRef, + xpath, + null, + namespaceService, + false); + + NodeRef prefRef; + if (nodes.size() == 1) + { + prefRef = nodes.get(0); + } + else + { + // create the preferences Node for this user + ChildAssociationRef childRef = nodeService.createNode( + configRef, + ContentModel.ASSOC_CONTAINS, + QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "preferences"), + ContentModel.TYPE_CMOBJECT); + + prefRef = childRef.getChildRef(); + } + + return prefRef; } } diff --git a/source/java/org/alfresco/web/bean/rules/RulesBean.java b/source/java/org/alfresco/web/bean/rules/RulesBean.java index de3cbecc77..e3dc802b17 100644 --- a/source/java/org/alfresco/web/bean/rules/RulesBean.java +++ b/source/java/org/alfresco/web/bean/rules/RulesBean.java @@ -327,7 +327,7 @@ public class RulesBean implements IContextListener * Inner class to wrap the Rule objects so we can expose a flag to indicate whether * the rule is a local or inherited rule */ - public class WrappedRule + public static class WrappedRule { private Rule rule; private NodeRef ruleNode; diff --git a/source/java/org/alfresco/web/bean/spaces/CreateSpaceWizard.java b/source/java/org/alfresco/web/bean/spaces/CreateSpaceWizard.java index ce66577e4c..6fffd00e31 100644 --- a/source/java/org/alfresco/web/bean/spaces/CreateSpaceWizard.java +++ b/source/java/org/alfresco/web/bean/spaces/CreateSpaceWizard.java @@ -95,6 +95,24 @@ public class CreateSpaceWizard extends BaseWizardBean this.saveAsTemplate = false; } + public String next() + { + // if the user has chosen to create the space from an existing + // space or from a template we need to find it's type to show + // the current set of icons. + if (this.createFrom.equals("existing") && this.existingSpaceId != null) + { + this.spaceType = this.nodeService.getType(this.existingSpaceId).toString(); + } + else if (this.createFrom.equals("template") && this.templateSpaceId != null) + { + NodeRef templateNode = new NodeRef(Repository.getStoreRef(), this.templateSpaceId); + this.spaceType = this.nodeService.getType(templateNode).toString(); + } + + return null; + } + @Override protected String finishImpl(FacesContext context, String outcome) throws Exception { @@ -611,6 +629,7 @@ public class CreateSpaceWizard extends BaseWizardBean // which the user can change during the advanced space wizard List icons = null; + List iconNames = new ArrayList(8); QName type = QName.createQName(this.spaceType); String typePrefixForm = type.toPrefixString(this.namespaceService); @@ -648,6 +667,7 @@ public class CreateSpaceWizard extends BaseWizardBean item.setValue(iconName); item.getAttributes().put("image", iconPath); icons.add(item); + iconNames.add(iconName); } } } @@ -660,9 +680,17 @@ public class CreateSpaceWizard extends BaseWizardBean this.icon = DEFAULT_SPACE_ICON_NAME; UIListItem item = new UIListItem(); - item.setValue("space-icon-default"); + item.setValue(DEFAULT_SPACE_ICON_NAME); item.getAttributes().put("image", "/images/icons/space-icon-default.gif"); icons.add(item); + iconNames.add(DEFAULT_SPACE_ICON_NAME); + } + + // make sure the current value for the icon is valid for the + // current list of icons about to be displayed + if (iconNames.contains(this.icon) == false) + { + this.icon = iconNames.get(0); } return icons; diff --git a/source/java/org/alfresco/web/bean/spaces/DeleteSpaceDialog.java b/source/java/org/alfresco/web/bean/spaces/DeleteSpaceDialog.java new file mode 100644 index 0000000000..5001db6ca6 --- /dev/null +++ b/source/java/org/alfresco/web/bean/spaces/DeleteSpaceDialog.java @@ -0,0 +1,100 @@ +package org.alfresco.web.bean.spaces; + +import java.text.MessageFormat; + +import javax.faces.application.FacesMessage; +import javax.faces.context.FacesContext; + +import org.alfresco.web.app.AlfrescoNavigationHandler; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.content.DeleteContentDialog; +import org.alfresco.web.bean.dialog.BaseDialogBean; +import org.alfresco.web.bean.repository.Node; +import org.alfresco.web.ui.common.Utils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Bean implementation for the "Delete Space" dialog + * + * @author gavinc + */ +public class DeleteSpaceDialog extends BaseDialogBean +{ + private static final Log logger = LogFactory.getLog(DeleteContentDialog.class); + + // ------------------------------------------------------------------------------ + // Dialog implementation + + @Override + protected String finishImpl(FacesContext context, String outcome) + throws Exception + { + // get the space to delete + Node node = this.browseBean.getActionSpace(); + if (node != null) + { + if (logger.isDebugEnabled()) + logger.debug("Trying to delete space: " + node.getId()); + + this.nodeService.deleteNode(node.getNodeRef()); + } + else + { + logger.warn("WARNING: delete called without a current Space!"); + } + + return outcome; + } + + @Override + protected String doPostCommitProcessing(FacesContext context, String outcome) + { + Node node = this.browseBean.getActionSpace(); + + // remove this node from the breadcrumb if required + this.browseBean.removeSpaceFromBreadcrumb(node); + + // add a message to inform the user that the delete was OK + String statusMsg = MessageFormat.format( + Application.getMessage(FacesContext.getCurrentInstance(), "status_space_deleted"), + new Object[]{node.getName()}); + Utils.addStatusMessage(FacesMessage.SEVERITY_INFO, statusMsg); + + // clear action context + this.browseBean.setActionSpace(null); + + // setting the outcome will show the browse view again + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + + AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse"; + } + + @Override + protected String getErrorMessageId() + { + return "error_delete_space"; + } + + @Override + public boolean getFinishButtonDisabled() + { + return false; + } + + // ------------------------------------------------------------------------------ + // Bean Getters and Setters + + /** + * Returns the confirmation to display to the user before deleting the content. + * + * @return The formatted message to display + */ + public String getConfirmMessage() + { + String fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(), + "delete_space_confirm"); + + return MessageFormat.format(fileConfirmMsg, + new Object[] {this.browseBean.getActionSpace().getName()}); + } +} diff --git a/source/java/org/alfresco/web/bean/users/UsersBean.java b/source/java/org/alfresco/web/bean/users/UsersBean.java index e6f906cfc3..a03197a32d 100644 --- a/source/java/org/alfresco/web/bean/users/UsersBean.java +++ b/source/java/org/alfresco/web/bean/users/UsersBean.java @@ -59,6 +59,7 @@ public class UsersBean implements IContextListener private static final String ERROR_USER_DELETE = "error_delete_user_object"; private static final String DEFAULT_OUTCOME = "manageUsers"; + private static final String DIALOG_CLOSE = "dialog:close"; /** NodeService bean reference */ protected NodeService nodeService; @@ -81,6 +82,7 @@ public class UsersBean implements IContextListener private List users = Collections.emptyList(); private String password = null; + private String oldPassword = null; private String confirm = null; private String searchCriteria = null; @@ -208,6 +210,22 @@ public class UsersBean implements IContextListener { this.password = password; } + + /** + * @return Returns the old password. + */ + public String getOldPassword() + { + return this.oldPassword; + } + + /** + * @param oldPassword The old password to set. + */ + public void setOldPassword(String oldPassword) + { + this.oldPassword = oldPassword; + } /** * @return Returns the person context. @@ -271,14 +289,9 @@ public class UsersBean implements IContextListener */ public String deleteOK() { - UserTransaction tx = null; - + FacesContext context = FacesContext.getCurrentInstance(); try { - FacesContext context = FacesContext.getCurrentInstance(); - tx = Repository.getUserTransaction(context); - tx.begin(); - String userName = (String)getPerson().getProperties().get("userName"); // we only delete the user auth if Alfresco is managing the authentication @@ -292,28 +305,24 @@ public class UsersBean implements IContextListener } catch (AuthenticationException authErr) { - Utils.addErrorMessage(Application.getMessage(FacesContext.getCurrentInstance(), ERROR_USER_DELETE)); + Utils.addErrorMessage(Application.getMessage(context, ERROR_USER_DELETE)); } } // delete the associated Person this.personService.deletePerson(userName); - // commit the transaction - tx.commit(); - // re-do the search to refresh the list search(); } catch (Throwable e) { // rollback the transaction - try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} - Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext - .getCurrentInstance(), ERROR_DELETE), e.getMessage()), e); + Utils.addErrorMessage(MessageFormat.format(Application.getMessage(context, + ERROR_DELETE), e.getMessage()), e); } - return DEFAULT_OUTCOME; + return DIALOG_CLOSE; } /** @@ -321,7 +330,7 @@ public class UsersBean implements IContextListener */ public String changePasswordOK() { - String outcome = DEFAULT_OUTCOME; + String outcome = DIALOG_CLOSE; if (this.password != null && this.confirm != null && this.password.equals(this.confirm)) { @@ -346,6 +355,39 @@ public class UsersBean implements IContextListener return outcome; } + + /** + * Action handler called for OK button press on Change My Password screen + * For this screen the user is required to enter their old password - effectively login. + */ + public String changeMyPasswordOK() + { + String outcome = DIALOG_CLOSE; + + if (this.password != null && this.confirm != null && this.password.equals(this.confirm)) + { + try + { + String userName = (String)this.person.getProperties().get(ContentModel.PROP_USERNAME); + this.authenticationService.updateAuthentication(userName, this.oldPassword.toCharArray(), this.password.toCharArray()); + } + catch (Exception e) + { + outcome = null; + Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext + .getCurrentInstance(), Repository.ERROR_GENERIC), e.getMessage()), e); + } + } + else + { + outcome = null; + Utils.addErrorMessage(Application.getMessage(FacesContext.getCurrentInstance(), + ERROR_PASSWORD_MATCH)); + } + + return outcome; + } + /** * Event handler called when the user wishes to search for a user diff --git a/source/java/org/alfresco/web/bean/wizard/BaseWizardBean.java b/source/java/org/alfresco/web/bean/wizard/BaseWizardBean.java index 4ed69c1065..8d1a1e914f 100644 --- a/source/java/org/alfresco/web/bean/wizard/BaseWizardBean.java +++ b/source/java/org/alfresco/web/bean/wizard/BaseWizardBean.java @@ -15,6 +15,16 @@ public abstract class BaseWizardBean extends BaseDialogBean implements IWizardBe { private static final String MSG_NOT_SET = "value_not_set"; + public String next() + { + return null; + } + + public String back() + { + return null; + } + public boolean getNextButtonDisabled() { return false; diff --git a/source/java/org/alfresco/web/bean/wizard/IWizardBean.java b/source/java/org/alfresco/web/bean/wizard/IWizardBean.java index b1e436a495..d8f46a7f0e 100644 --- a/source/java/org/alfresco/web/bean/wizard/IWizardBean.java +++ b/source/java/org/alfresco/web/bean/wizard/IWizardBean.java @@ -9,6 +9,20 @@ import org.alfresco.web.bean.dialog.IDialogBean; */ public interface IWizardBean extends IDialogBean { + /** + * Called when the next button is pressed by the user + * + * @return Reserved for future use + */ + public String next(); + + /** + * Called when the back button is pressed by the user + * + * @return Reserved for future use + */ + public String back(); + /** * Returns the label to use for the next button * diff --git a/source/java/org/alfresco/web/bean/wizard/InviteUsersWizard.java b/source/java/org/alfresco/web/bean/wizard/InviteUsersWizard.java index 0f38fee2aa..df0afdfb48 100644 --- a/source/java/org/alfresco/web/bean/wizard/InviteUsersWizard.java +++ b/source/java/org/alfresco/web/bean/wizard/InviteUsersWizard.java @@ -297,7 +297,7 @@ public abstract class InviteUsersWizard extends AbstractWizardBean NodeRef templateRef = new NodeRef(Repository.getStoreRef(), this.usingTemplate); ServiceRegistry services = Repository.getServiceRegistry(fc); Map model = DefaultModelHelper.buildDefaultModel( - services, Application.getCurrentUser(fc)); + services, Application.getCurrentUser(fc), templateRef); model.put("role", roleText); model.put("space", new TemplateNode(node, Repository.getServiceRegistry(fc), null)); diff --git a/source/java/org/alfresco/web/bean/wizard/WizardManager.java b/source/java/org/alfresco/web/bean/wizard/WizardManager.java index 79c587f8c7..f708413da4 100644 --- a/source/java/org/alfresco/web/bean/wizard/WizardManager.java +++ b/source/java/org/alfresco/web/bean/wizard/WizardManager.java @@ -412,8 +412,8 @@ public class WizardManager if (logger.isDebugEnabled()) logger.debug("next called, current step is now: " + this.currentStep); - // TODO: place a hook in here to call the wizard bean so it can override - // what step comes next thus overrriding the wizard manager + // tell the wizard the next button has been pressed + this.currentWizard.next(); determineCurrentPage(); } @@ -430,8 +430,8 @@ public class WizardManager if (logger.isDebugEnabled()) logger.debug("back called, current step is now: " + this.currentStep); - // TODO: place a hook in here to call the wizard bean so it can override - // what step comes next thus overrriding the wizard manager + // tell the wizard the back button has been pressed + this.currentWizard.back(); determineCurrentPage(); } diff --git a/source/java/org/alfresco/web/config/ActionsConfigElement.java b/source/java/org/alfresco/web/config/ActionsConfigElement.java index 4331d6b85a..b57336ff36 100644 --- a/source/java/org/alfresco/web/config/ActionsConfigElement.java +++ b/source/java/org/alfresco/web/config/ActionsConfigElement.java @@ -288,7 +288,7 @@ public class ActionsConfigElement extends ConfigElementAdapter return this.actions; } - /*pacakge*/ Set getHiddenActions() + /*package*/ Set getHiddenActions() { return this.hiddenActions; } diff --git a/source/java/org/alfresco/web/config/AspectEvaluator.java b/source/java/org/alfresco/web/config/AspectEvaluator.java index 2c52f24bf7..164228e1e8 100644 --- a/source/java/org/alfresco/web/config/AspectEvaluator.java +++ b/source/java/org/alfresco/web/config/AspectEvaluator.java @@ -28,7 +28,7 @@ import org.alfresco.web.bean.repository.Repository; * * @author gavinc */ -public class AspectEvaluator implements Evaluator +public final class AspectEvaluator implements Evaluator { /** * Determines whether the given aspect is applied to the given object @@ -51,5 +51,4 @@ public class AspectEvaluator implements Evaluator return result; } - } diff --git a/source/java/org/alfresco/web/config/ClientConfigElement.java b/source/java/org/alfresco/web/config/ClientConfigElement.java index fc7488ceea..4c75bfcc8d 100644 --- a/source/java/org/alfresco/web/config/ClientConfigElement.java +++ b/source/java/org/alfresco/web/config/ClientConfigElement.java @@ -39,6 +39,7 @@ public class ClientConfigElement extends ConfigElementAdapter private String helpUrl = null; private String editLinkType = "http"; private String homeSpacePermission = null; + private boolean ajaxEnabled = false; /** * Default Constructor @@ -329,4 +330,22 @@ public class ClientConfigElement extends ConfigElementAdapter { this.homeSpacePermission = homeSpacePermission; } + + /** + * @return Returns whether AJAX support is enabled in the client + */ + public boolean isAjaxEnabled() + { + return this.ajaxEnabled; + } + + /** + * Sets whether AJAX support is enabled in the client + * + * @param ajaxEnabled + */ + /*package*/ void setAjaxEnabled(boolean ajaxEnabled) + { + this.ajaxEnabled = ajaxEnabled; + } } diff --git a/source/java/org/alfresco/web/config/ClientElementReader.java b/source/java/org/alfresco/web/config/ClientElementReader.java index 73cf1ecc5c..00feb8377f 100644 --- a/source/java/org/alfresco/web/config/ClientElementReader.java +++ b/source/java/org/alfresco/web/config/ClientElementReader.java @@ -39,6 +39,7 @@ public class ClientElementReader implements ConfigElementReader public static final String ELEMENT_HOMESPACEPERMISSION = "home-space-permission"; public static final String ELEMENT_FROMEMAILADDRESS = "from-email-address"; public static final String ELEMENT_SHELFVISIBLE = "shelf-visible"; + public static final String ELEMENT_AJAX_ENABLED = "ajax-enabled"; /** * @see org.alfresco.config.xml.elementreader.ConfigElementReader#parse(org.dom4j.Element) @@ -136,6 +137,13 @@ public class ClientElementReader implements ConfigElementReader { configElement.setLoginPage(loginPage.getTextTrim()); } + + // get the ajax enabled flag + Element ajaxEnabled = element.element(ELEMENT_AJAX_ENABLED); + if (ajaxEnabled != null) + { + configElement.setAjaxEnabled(Boolean.parseBoolean(ajaxEnabled.getTextTrim())); + } } return configElement; diff --git a/source/java/org/alfresco/web/config/DashboardsConfigElement.java b/source/java/org/alfresco/web/config/DashboardsConfigElement.java new file mode 100644 index 0000000000..d35e0256e5 --- /dev/null +++ b/source/java/org/alfresco/web/config/DashboardsConfigElement.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.web.config; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.config.ConfigElement; +import org.alfresco.config.ConfigException; +import org.alfresco.config.element.ConfigElementAdapter; + +/** + * Dashboard config element. + * + * @author Kevin Roast + */ +public class DashboardsConfigElement extends ConfigElementAdapter +{ + public static final String CONFIG_ELEMENT_ID = "dashboards"; + + private Map layoutDefs = new LinkedHashMap(4, 1.0f); + private Map dashletDefs = new LinkedHashMap(8, 1.0f); + + /** + * Default constructor + */ + public DashboardsConfigElement() + { + super(CONFIG_ELEMENT_ID); + } + + /** + * @param name + */ + public DashboardsConfigElement(String name) + { + super(name); + } + + /** + * @see org.alfresco.config.element.ConfigElementAdapter#getChildren() + */ + public List getChildren() + { + throw new ConfigException("Reading the Dashboards config via the generic interfaces is not supported"); + } + + /** + * @see org.alfresco.config.element.ConfigElementAdapter#combine(org.alfresco.config.ConfigElement) + */ + public ConfigElement combine(ConfigElement configElement) + { + DashboardsConfigElement newElement = (DashboardsConfigElement)configElement; + DashboardsConfigElement combinedElement = new DashboardsConfigElement(); + + // put all into combined from this and then from new to override any already present + combinedElement.dashletDefs.putAll(this.dashletDefs); + combinedElement.dashletDefs.putAll(newElement.dashletDefs); + + combinedElement.layoutDefs.putAll(this.layoutDefs); + combinedElement.layoutDefs.putAll(newElement.layoutDefs); + + return combinedElement; + } + + /*package*/ void addLayoutDefinition(LayoutDefinition def) + { + this.layoutDefs.put(def.Id, def); + } + + public LayoutDefinition getLayoutDefinition(String id) + { + return this.layoutDefs.get(id); + } + + /*package*/ void addDashletDefinition(DashletDefinition def) + { + this.dashletDefs.put(def.Id, def); + } + + public DashletDefinition getDashletDefinition(String id) + { + return this.dashletDefs.get(id); + } + + public Collection getLayouts() + { + return this.layoutDefs.values(); + } + + public Collection getDashlets() + { + return this.dashletDefs.values(); + } + + /** + * Structure class for the definition of a dashboard page layout + */ + public static class LayoutDefinition + { + LayoutDefinition(String id) + { + this.Id = id; + } + + public String Id; + public String Image; + public int Columns; + public int ColumnLength; + public String Label; + public String LabelId; + public String Description; + public String DescriptionId; + public String JSPPage; + } + + /** + * Structure class for the definition of a dashboard dashlet component + */ + public static class DashletDefinition + { + DashletDefinition(String id) + { + this.Id = id; + } + + public String Id; + public boolean AllowNarrow = true; + public String Label; + public String LabelId; + public String Description; + public String DescriptionId; + public String JSPPage; + } +} diff --git a/source/java/org/alfresco/web/config/DashboardsElementReader.java b/source/java/org/alfresco/web/config/DashboardsElementReader.java new file mode 100644 index 0000000000..b9e3e08079 --- /dev/null +++ b/source/java/org/alfresco/web/config/DashboardsElementReader.java @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.web.config; + +import java.util.Iterator; + +import org.alfresco.config.ConfigElement; +import org.alfresco.config.ConfigException; +import org.alfresco.config.xml.elementreader.ConfigElementReader; +import org.alfresco.web.config.DashboardsConfigElement.DashletDefinition; +import org.alfresco.web.config.DashboardsConfigElement.LayoutDefinition; +import org.dom4j.Element; + +/** + * Reader for the 'dashboards' config element and child elements. + * + * @author Kevin Roast + */ +public class DashboardsElementReader implements ConfigElementReader +{ + public static final String ELEMENT_DASHBOARDS = "dashboards"; + public static final String ELEMENT_LAYOUTS = "layouts"; + public static final String ELEMENT_LAYOUT = "layout"; + public static final String ELEMENT_DASHLETS = "dashlets"; + public static final String ELEMENT_DASHLET = "dashlet"; + public static final String ATTR_ID = "id"; + public static final String ATTR_COLUMNS = "columns"; + public static final String ATTR_COLUMNLENGTH = "column-length"; + public static final String ATTR_IMAGE = "image"; + public static final String ATTR_LABEL = "label"; + public static final String ATTR_DESCRIPTION = "description"; + public static final String ATTR_LABELID = "label-id"; + public static final String ATTR_DESCRIPTIONID = "description-id"; + public static final String ATTR_JSP = "jsp"; + public static final String ATTR_ALLOWNARROW = "allow-narrow"; + + /** + * @see org.alfresco.config.xml.elementreader.ConfigElementReader#parse(org.dom4j.Element) + */ + @SuppressWarnings("unchecked") + public ConfigElement parse(Element element) + { + DashboardsConfigElement configElement = new DashboardsConfigElement(); + + if (element != null) + { + if (DashboardsConfigElement.CONFIG_ELEMENT_ID.equals(element.getName()) == false) + { + throw new ConfigException("DashboardsElementReader can only process elements of type 'dashboards'"); + } + + Element layoutsElement = element.element(ELEMENT_LAYOUTS); + if (layoutsElement != null) + { + Iterator layoutsItr = layoutsElement.elementIterator(ELEMENT_LAYOUT); + while (layoutsItr.hasNext()) + { + LayoutDefinition layoutDef = parseLayoutDefinition(layoutsItr.next()); + configElement.addLayoutDefinition(layoutDef); + } + } + + Element dashletsElement = element.element(ELEMENT_DASHLETS); + if (dashletsElement != null) + { + Iterator dashletsItr = dashletsElement.elementIterator(ELEMENT_DASHLET); + while (dashletsItr.hasNext()) + { + DashletDefinition dashletDef = parseDashletDefinition(dashletsItr.next()); + configElement.addDashletDefinition(dashletDef); + } + } + } + + return configElement; + } + + /** + * Parse a single Layout definition from config. + * + * @param config + * + * @return LayoutDefinition for the specified config element. + */ + private static LayoutDefinition parseLayoutDefinition(Element config) + { + String id = getMandatoryLayoutAttributeValue(config, ATTR_ID); + + LayoutDefinition def = new LayoutDefinition(id); + + String columns = getMandatoryLayoutAttributeValue(config, ATTR_COLUMNS); + def.Columns = Integer.parseInt(columns); + String columnLength = getMandatoryLayoutAttributeValue(config, ATTR_COLUMNLENGTH); + def.ColumnLength = Integer.parseInt(columnLength); + def.Image = getMandatoryLayoutAttributeValue(config, ATTR_IMAGE); + def.JSPPage = getMandatoryLayoutAttributeValue(config, ATTR_JSP); + String label = config.attributeValue(ATTR_LABEL); + String labelId = config.attributeValue(ATTR_LABELID); + if ((label == null || label.length() == 0) && (labelId == null || labelId.length() == 0)) + { + throw new ConfigException("Either 'label' or 'label-id' attribute must be specified for Dashboard 'layout' configuration element."); + } + def.Label = label; + def.LabelId = labelId; + String description = config.attributeValue(ATTR_DESCRIPTION); + String descriptionId = config.attributeValue(ATTR_DESCRIPTIONID); + if ((description == null || description.length() == 0) && (descriptionId == null || descriptionId.length() == 0)) + { + throw new ConfigException("Either 'description' or 'description-id' attribute must be specified for Dashboard 'layout' configuration element."); + } + def.Description = description; + def.DescriptionId = descriptionId; + + return def; + } + + /** + * Return a mandatory layout attribute layout. Throw an exception if the value is not found. + * + * @param config + * @param attr + * + * @return String value + */ + private static String getMandatoryLayoutAttributeValue(Element config, String attr) + { + String value = config.attributeValue(attr); + if (value == null || value.length() == 0) + { + throw new ConfigException("Missing mandatory '" + attr + "' attribute for Dashboard 'layout' configuration element."); + } + return value; + } + + /** + * Parse a single Dashlet definition from config. + * + * @param config + * + * @return DashletDefinition for the specified config element. + */ + private static DashletDefinition parseDashletDefinition(Element config) + { + String id = getMandatoryDashletAttributeValue(config, ATTR_ID); + + DashletDefinition def = new DashletDefinition(id); + + String allowNarrow = config.attributeValue(ATTR_ALLOWNARROW); + if (allowNarrow != null && allowNarrow.length() != 0) + { + def.AllowNarrow = Boolean.parseBoolean(allowNarrow); + } + def.JSPPage = getMandatoryDashletAttributeValue(config, ATTR_JSP); + String label = config.attributeValue(ATTR_LABEL); + String labelId = config.attributeValue(ATTR_LABELID); + if ((label == null || label.length() == 0) && (labelId == null || labelId.length() == 0)) + { + throw new ConfigException("Either 'label' or 'label-id' attribute must be specified for Dashboard 'dashlet' configuration element."); + } + def.Label = label; + def.LabelId = labelId; + String description = config.attributeValue(ATTR_DESCRIPTION); + String descriptionId = config.attributeValue(ATTR_DESCRIPTIONID); + if ((description == null || description.length() == 0) && (descriptionId == null || descriptionId.length() == 0)) + { + throw new ConfigException("Either 'description' or 'description-id' attribute must be specified for Dashboard 'dashlet' configuration element."); + } + def.Description = description; + def.DescriptionId = descriptionId; + + return def; + } + + /** + * Return a mandatory dashlet attribute layout. Throw an exception if the value is not found. + * + * @param config + * @param attr + * + * @return String value + */ + private static String getMandatoryDashletAttributeValue(Element config, String attr) + { + String value = config.attributeValue(attr); + if (value == null || value.length() == 0) + { + throw new ConfigException("Missing mandatory '" + attr + "' attribute for Dashboard 'dashlet' configuration element."); + } + return value; + } +} diff --git a/source/java/org/alfresco/web/data/Sort.java b/source/java/org/alfresco/web/data/Sort.java index 67bc8fac81..fce5bcaca2 100644 --- a/source/java/org/alfresco/web/data/Sort.java +++ b/source/java/org/alfresco/web/data/Sort.java @@ -94,6 +94,7 @@ public abstract class Sort * * @param collator the Collator object to use to build String keys */ + @SuppressWarnings("unchecked") protected List buildCollationKeys(Collator collator) { List data = this.data; @@ -260,6 +261,7 @@ public abstract class Sort * Given the array and two indices, swap the two items in the * array. */ + @SuppressWarnings("unchecked") protected void swap(final List v, final int a, final int b) { Object temp = v.get(a); @@ -294,7 +296,7 @@ public abstract class Sort // ------------------------------------------------------------------------------ // Inner classes for data type comparison - private class SimpleComparator implements Comparator + private static class SimpleComparator implements Comparator { /** * @see org.alfresco.web.data.IDataComparator#compare(java.lang.Object, java.lang.Object) @@ -308,7 +310,7 @@ public abstract class Sort } } - private class SimpleStringComparator implements Comparator + private static class SimpleStringComparator implements Comparator { /** * @see org.alfresco.web.data.IDataComparator#compare(java.lang.Object, java.lang.Object) @@ -322,7 +324,7 @@ public abstract class Sort } } - private class StringComparator implements Comparator + private static class StringComparator implements Comparator { /** * @see org.alfresco.web.data.IDataComparator#compare(java.lang.Object, java.lang.Object) @@ -336,7 +338,7 @@ public abstract class Sort } } - private class IntegerComparator implements Comparator + private static class IntegerComparator implements Comparator { /** * @see org.alfresco.web.data.IDataComparator#compare(java.lang.Object, java.lang.Object) @@ -350,7 +352,7 @@ public abstract class Sort } } - private class FloatComparator implements Comparator + private static class FloatComparator implements Comparator { /** * @see org.alfresco.web.data.IDataComparator#compare(java.lang.Object, java.lang.Object) @@ -364,7 +366,7 @@ public abstract class Sort } } - private class LongComparator implements Comparator + private static class LongComparator implements Comparator { /** * @see org.alfresco.web.data.IDataComparator#compare(java.lang.Object, java.lang.Object) @@ -378,7 +380,7 @@ public abstract class Sort } } - private class BooleanComparator implements Comparator + private static class BooleanComparator implements Comparator { /** * @see org.alfresco.web.data.IDataComparator#compare(java.lang.Object, java.lang.Object) @@ -392,7 +394,7 @@ public abstract class Sort } } - private class DateComparator implements Comparator + private static class DateComparator implements Comparator { /** * @see org.alfresco.web.data.IDataComparator#compare(java.lang.Object, java.lang.Object) diff --git a/source/java/org/alfresco/web/ui/common/Utils.java b/source/java/org/alfresco/web/ui/common/Utils.java index 7f7ee84716..182fd34003 100644 --- a/source/java/org/alfresco/web/ui/common/Utils.java +++ b/source/java/org/alfresco/web/ui/common/Utils.java @@ -88,6 +88,8 @@ public final class Utils private static final String DEFAULT_FILE_IMAGE16 = IMAGE_PREFIX16 + "_default" + IMAGE_POSTFIX; private static final String DEFAULT_FILE_IMAGE32 = IMAGE_PREFIX32 + "_default" + IMAGE_POSTFIX; + private static final String AJAX_SCRIPTS_WRITTEN = "_alfAjaxScriptsWritten"; + private static final Map s_fileExtensionMap = new HashMap(89, 1.0f); private static Log logger = LogFactory.getLog(Utils.class); @@ -1238,4 +1240,37 @@ public final class Utils return description; } + + /** + * Writes the script tags for including AJAX support, ensuring they + * only get written once per page render. + * + * @param context Faces context + * @param out The response writer + */ + @SuppressWarnings("unchecked") + public static void writeAjaxScripts(FacesContext context, ResponseWriter out) + throws IOException + { + Object present = context.getExternalContext().getRequestMap().get(AJAX_SCRIPTS_WRITTEN); + + if (present == null) + { + // write out the scripts + out.write("\n\n"); + out.write("\n"); + + // write out a global variable to hold the webapp context path + out.write("\n"); + + // add marker to request + context.getExternalContext().getRequestMap().put(AJAX_SCRIPTS_WRITTEN, Boolean.TRUE); + } + } } diff --git a/source/java/org/alfresco/web/ui/common/component/UIImagePicker.java b/source/java/org/alfresco/web/ui/common/component/UIImagePicker.java index c6864714e6..c26a045415 100644 --- a/source/java/org/alfresco/web/ui/common/component/UIImagePicker.java +++ b/source/java/org/alfresco/web/ui/common/component/UIImagePicker.java @@ -19,9 +19,6 @@ package org.alfresco.web.ui.common.component; import javax.faces.component.UIInput; import javax.faces.context.FacesContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - /** * Component to represent a selectable list of images * @@ -29,8 +26,6 @@ import org.apache.commons.logging.LogFactory; */ public class UIImagePicker extends UIInput { - private static Log logger = LogFactory.getLog(UIImagePicker.class); - /** * Default constructor */ diff --git a/source/java/org/alfresco/web/ui/common/component/data/UISortLink.java b/source/java/org/alfresco/web/ui/common/component/data/UISortLink.java index 1f8777cc0c..26befaef28 100644 --- a/source/java/org/alfresco/web/ui/common/component/data/UISortLink.java +++ b/source/java/org/alfresco/web/ui/common/component/data/UISortLink.java @@ -65,7 +65,7 @@ public class UISortLink extends UICommand boolean bPreviouslySorted = false; boolean descending = true; String lastSortedColumn = dataContainer.getCurrentSortColumn(); - if (lastSortedColumn == (String)getValue()) + if (lastSortedColumn != null && lastSortedColumn.equals(getValue())) { descending = !dataContainer.isCurrentSortDescending(); bPreviouslySorted = true; diff --git a/source/java/org/alfresco/web/ui/common/component/description/UIDynamicDescription.java b/source/java/org/alfresco/web/ui/common/component/description/UIDynamicDescription.java index ad5bdc2f68..cce124be19 100644 --- a/source/java/org/alfresco/web/ui/common/component/description/UIDynamicDescription.java +++ b/source/java/org/alfresco/web/ui/common/component/description/UIDynamicDescription.java @@ -28,8 +28,6 @@ import javax.faces.el.ValueBinding; import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.component.SelfRenderingComponent; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; /** * Dynamic description component that switches text based on the events @@ -39,7 +37,6 @@ import org.apache.commons.logging.LogFactory; */ public class UIDynamicDescription extends SelfRenderingComponent { - private static Log logger = LogFactory.getLog(UIDynamicDescription.class); private String selected; private String functionName; @@ -141,6 +138,7 @@ public class UIDynamicDescription extends SelfRenderingComponent /** * @see javax.faces.component.UIComponent#encodeChildren(javax.faces.context.FacesContext) */ + @SuppressWarnings("unchecked") public void encodeChildren(FacesContext context) throws IOException { if (this.isRendered() == false) @@ -240,6 +238,7 @@ public class UIDynamicDescription extends SelfRenderingComponent * @param context The faces context * @param descriptions The descriptions to render */ + @SuppressWarnings("unchecked") private void renderDescriptions(FacesContext context, UIDescriptions descriptions) throws IOException { diff --git a/source/java/org/alfresco/web/ui/common/component/evaluator/BaseEvaluator.java b/source/java/org/alfresco/web/ui/common/component/evaluator/BaseEvaluator.java index 58d38b667a..98c14651cf 100644 --- a/source/java/org/alfresco/web/ui/common/component/evaluator/BaseEvaluator.java +++ b/source/java/org/alfresco/web/ui/common/component/evaluator/BaseEvaluator.java @@ -129,7 +129,7 @@ public abstract class BaseEvaluator extends SelfRenderingComponent public abstract boolean evaluate(); - protected static Logger s_logger = Logger.getLogger(BaseEvaluator.class); + protected static final Logger s_logger = Logger.getLogger(BaseEvaluator.class); /** the value to be evaluated against */ private Object value; diff --git a/source/java/org/alfresco/web/ui/common/tag/ActionLinkTag.java b/source/java/org/alfresco/web/ui/common/tag/ActionLinkTag.java index 979872f661..e3931a3a86 100644 --- a/source/java/org/alfresco/web/ui/common/tag/ActionLinkTag.java +++ b/source/java/org/alfresco/web/ui/common/tag/ActionLinkTag.java @@ -57,7 +57,7 @@ public class ActionLinkTag extends HtmlComponentTag setStringProperty(component, "value", this.value); setStringProperty(component, "target", this.target); setStringProperty(component, "onclick", this.onclick); - + setBooleanProperty(component, "immediate", this.immediate); // TODO: Add image width/height properties } @@ -77,6 +77,7 @@ public class ActionLinkTag extends HtmlComponentTag this.href = null; this.target = null; this.onclick = null; + this.immediate = null; } /** @@ -178,6 +179,11 @@ public class ActionLinkTag extends HtmlComponentTag { this.onclick = onclick; } + + public void setImmediate(String immediate) + { + this.immediate = immediate; + } /** the target */ private String target; @@ -208,4 +214,7 @@ public class ActionLinkTag extends HtmlComponentTag /** the onclick handler */ private String onclick; + + /** the immediate flag */ + private String immediate; } diff --git a/source/java/org/alfresco/web/ui/repo/component/UINodeInfo.java b/source/java/org/alfresco/web/ui/repo/component/UINodeInfo.java new file mode 100644 index 0000000000..e894e5bf19 --- /dev/null +++ b/source/java/org/alfresco/web/ui/repo/component/UINodeInfo.java @@ -0,0 +1,137 @@ +package org.alfresco.web.ui.repo.component; + +import java.io.IOException; + +import javax.faces.context.FacesContext; +import javax.faces.context.ResponseWriter; +import javax.faces.el.ValueBinding; + +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.ui.common.Utils; +import org.alfresco.web.ui.common.component.SelfRenderingComponent; + +/** + * JSF component that displays information about a node. + *

+ * The node to show information on + * + * @author gavinc + */ +public class UINodeInfo extends SelfRenderingComponent +{ + protected final static String NODE_INFO_SCRIPTS_WRITTEN = "_alfNodeInfoScripts"; + + protected Object value = null; + + // ------------------------------------------------------------------------------ + // Component Impl + + @Override + public String getFamily() + { + return "org.alfresco.faces.NodeInfo"; + } + + @Override + public void restoreState(FacesContext context, Object state) + { + Object values[] = (Object[])state; + // standard component attributes are restored by the super class + super.restoreState(context, values[0]); + this.value = values[1]; + } + + @Override + public Object saveState(FacesContext context) + { + Object values[] = new Object[8]; + // standard component attributes are saved by the super class + values[0] = super.saveState(context); + values[1] = this.value; + return values; + } + + @Override + @SuppressWarnings("unchecked") + public void encodeBegin(FacesContext context) throws IOException + { + if (!isRendered()) return; + + // if AJAX is disabled don't render anything + if (Application.getClientConfig(context).isAjaxEnabled()) + { + ResponseWriter out = context.getResponseWriter(); + + // output the scripts required by the component (checks are + // made to make sure the scripts are only written once) + Utils.writeAjaxScripts(context, out); + + // write out the JavaScript specific to the NodeInfo component, + // again, make sure it's only done once + Object present = context.getExternalContext().getRequestMap(). + get(NODE_INFO_SCRIPTS_WRITTEN); + if (present == null) + { + out.write("\n"); + + context.getExternalContext().getRequestMap().put( + NODE_INFO_SCRIPTS_WRITTEN, Boolean.TRUE); + } + + // wrap the child components in a that has the onmouseover + // event which kicks off the request for node information + String id = (String)this.getValue(); + out.write(""); + } + } + + @Override + public void encodeEnd(FacesContext context) throws IOException + { + if (!isRendered()) return; + + // if AJAX is disabled don't render anything + if (Application.getClientConfig(context).isAjaxEnabled()) + { + context.getResponseWriter().write(""); + } + } + + // ------------------------------------------------------------------------------ + // Strongly typed component property accessors + + /** + * Get the value - the value is used in a equals() match against the current value in the + * parent ModeList component to set the selected item. + * + * @return the value + */ + public Object getValue() + { + ValueBinding vb = getValueBinding("value"); + if (vb != null) + { + this.value = vb.getValue(getFacesContext()); + } + + return this.value; + } + + /** + * Set the value - the value is used in a equals() match against the current value in the + * parent ModeList component to set the selected item. + * + * @param value the value + */ + public void setValue(Object value) + { + this.value = value; + } +} diff --git a/source/java/org/alfresco/web/ui/repo/component/property/UIPropertySheet.java b/source/java/org/alfresco/web/ui/repo/component/property/UIPropertySheet.java index cdd6cf3218..d7d4b75bef 100644 --- a/source/java/org/alfresco/web/ui/repo/component/property/UIPropertySheet.java +++ b/source/java/org/alfresco/web/ui/repo/component/property/UIPropertySheet.java @@ -739,37 +739,40 @@ public class UIPropertySheet extends UIPanel implements NamingContainer } // now setup the common stuff across all component types - FacesHelper.setupComponentId(context, propSheetItem, id); - propSheetItem.setName(item.getName()); - propSheetItem.setConverter(item.getConverter()); - propSheetItem.setComponentGenerator(item.getComponentGenerator()); - propSheetItem.setIgnoreIfMissing(item.getIgnoreIfMissing()); - - String displayLabel = item.getDisplayLabel(); - if (item.getDisplayLabelId() != null) + if (propSheetItem != null) { - String label = Application.getMessage(context, item.getDisplayLabelId()); - if (label != null) + FacesHelper.setupComponentId(context, propSheetItem, id); + propSheetItem.setName(item.getName()); + propSheetItem.setConverter(item.getConverter()); + propSheetItem.setComponentGenerator(item.getComponentGenerator()); + propSheetItem.setIgnoreIfMissing(item.getIgnoreIfMissing()); + + String displayLabel = item.getDisplayLabel(); + if (item.getDisplayLabelId() != null) { - displayLabel = label; + String label = Application.getMessage(context, item.getDisplayLabelId()); + if (label != null) + { + displayLabel = label; + } } + propSheetItem.setDisplayLabel(displayLabel); + + // if this property sheet is set as read only or the config says the property + // should be read only set it as such + if (isReadOnly() || item.isReadOnly()) + { + propSheetItem.setReadOnly(true); + } + + this.getChildren().add(propSheetItem); + + if (logger.isDebugEnabled()) + logger.debug("Created property sheet item component " + propSheetItem + "(" + + propSheetItem.getClientId(context) + + ") for '" + item.getName() + + "' and added it to property sheet " + this); } - propSheetItem.setDisplayLabel(displayLabel); - - // if this property sheet is set as read only or the config says the property - // should be read only set it as such - if (isReadOnly() || item.isReadOnly()) - { - propSheetItem.setReadOnly(true); - } - - this.getChildren().add(propSheetItem); - - if (logger.isDebugEnabled()) - logger.debug("Created property sheet item component " + propSheetItem + "(" + - propSheetItem.getClientId(context) + - ") for '" + item.getName() + - "' and added it to property sheet " + this); } } diff --git a/source/java/org/alfresco/web/ui/repo/component/template/DefaultModelHelper.java b/source/java/org/alfresco/web/ui/repo/component/template/DefaultModelHelper.java index 22721ceb8b..f7676bbcc7 100644 --- a/source/java/org/alfresco/web/ui/repo/component/template/DefaultModelHelper.java +++ b/source/java/org/alfresco/web/ui/repo/component/template/DefaultModelHelper.java @@ -58,7 +58,7 @@ public class DefaultModelHelper * * @return Map containing the default model. */ - public static Map buildDefaultModel(ServiceRegistry services, User user) + public static Map buildDefaultModel(ServiceRegistry services, User user, NodeRef template) { if (services == null) { @@ -85,6 +85,12 @@ public class DefaultModelHelper // supply the current user Node as "person" root.put("person", new TemplateNode(user.getPerson(), services, imageResolver)); + // add the template itself as "template" if it comes from content on a node + if (template != null) + { + root.put("template", new TemplateNode(template, services, imageResolver)); + } + // current date/time is useful to have and isn't supplied by FreeMarker by default root.put("date", new Date()); @@ -97,7 +103,7 @@ public class DefaultModelHelper } /** Template Image resolver helper */ - public static TemplateImageResolver imageResolver = new TemplateImageResolver() + public static final TemplateImageResolver imageResolver = new TemplateImageResolver() { public String resolveImagePathForName(String filename, boolean small) { diff --git a/source/java/org/alfresco/web/ui/repo/component/template/UITemplate.java b/source/java/org/alfresco/web/ui/repo/component/template/UITemplate.java index fc429f431d..0c362c3793 100644 --- a/source/java/org/alfresco/web/ui/repo/component/template/UITemplate.java +++ b/source/java/org/alfresco/web/ui/repo/component/template/UITemplate.java @@ -17,21 +17,16 @@ package org.alfresco.web.ui.repo.component.template; import java.io.IOException; -import java.util.Date; -import java.util.HashMap; import java.util.Map; import javax.faces.context.FacesContext; import javax.faces.el.ValueBinding; -import org.alfresco.repo.template.DateCompareMethod; -import org.alfresco.repo.template.HasAspectMethod; -import org.alfresco.repo.template.I18NMessageMethod; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.TemplateException; import org.alfresco.service.cmr.repository.TemplateImageResolver; -import org.alfresco.service.cmr.repository.TemplateNode; import org.alfresco.service.cmr.repository.TemplateService; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Repository; @@ -108,9 +103,6 @@ public class UITemplate extends SelfRenderingComponent return; } - // get the data model to use - building default if required - Object model = getModel(); - // get the template to process String template = getTemplate(); if (template != null && template.length() != 0) @@ -125,6 +117,9 @@ public class UITemplate extends SelfRenderingComponent startTime = System.currentTimeMillis(); } + // get the data model to use - building default if required + Object model = getModel(); + // process the template against the model try { @@ -195,7 +190,16 @@ public class UITemplate extends SelfRenderingComponent FacesContext fc = FacesContext.getCurrentInstance(); ServiceRegistry services = Repository.getServiceRegistry(fc); User user = Application.getCurrentUser(fc); - Map root = DefaultModelHelper.buildDefaultModel(services, user); + + // add the template itself to the model + NodeRef templateRef = null; + if (getTemplate().indexOf(StoreRef.URI_FILLER) != -1) + { + // found a noderef template + templateRef = new NodeRef(getTemplate()); + } + + Map root = DefaultModelHelper.buildDefaultModel(services, user, templateRef); // merge models if (model instanceof Map) diff --git a/source/java/org/alfresco/web/ui/repo/renderer/NodeDescendantsLinkRenderer.java b/source/java/org/alfresco/web/ui/repo/renderer/NodeDescendantsLinkRenderer.java index ce762fcf7e..f2d2ee56dd 100644 --- a/source/java/org/alfresco/web/ui/repo/renderer/NodeDescendantsLinkRenderer.java +++ b/source/java/org/alfresco/web/ui/repo/renderer/NodeDescendantsLinkRenderer.java @@ -67,7 +67,6 @@ public class NodeDescendantsLinkRenderer extends BaseRenderer int separatorIndex = value.indexOf(NamingContainer.SEPARATOR_CHAR); String selectedNodeId = value.substring(0, separatorIndex); boolean isParent = Boolean.parseBoolean(value.substring(separatorIndex + 1)); - NodeService service = getNodeService(context); NodeRef ref = new NodeRef(Repository.getStoreRef(), selectedNodeId); UINodeDescendants.NodeSelectedEvent event = new UINodeDescendants.NodeSelectedEvent(component, ref, isParent); diff --git a/source/java/org/alfresco/web/ui/repo/tag/NodeInfoTag.java b/source/java/org/alfresco/web/ui/repo/tag/NodeInfoTag.java new file mode 100644 index 0000000000..5796edbe0a --- /dev/null +++ b/source/java/org/alfresco/web/ui/repo/tag/NodeInfoTag.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.web.ui.repo.tag; + +import javax.faces.component.UIComponent; + +import org.alfresco.web.ui.common.tag.HtmlComponentTag; + +/** + * Tag class for the UINodeInfo component + * + * @author gavinc + */ +public class NodeInfoTag extends HtmlComponentTag +{ + private String value; + + /** + * @see javax.faces.webapp.UIComponentTag#getComponentType() + */ + public String getComponentType() + { + return "org.alfresco.faces.NodeInfo"; + } + + /** + * @see javax.faces.webapp.UIComponentTag#getRendererType() + */ + public String getRendererType() + { + return null; + } + + /** + * @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent) + */ + protected void setProperties(UIComponent component) + { + super.setProperties(component); + + setStringBindingProperty(component, "value", this.value); + } + + /** + * @see org.alfresco.web.ui.common.tag.HtmlComponentTag#release() + */ + public void release() + { + super.release(); + + this.value = null; + } + + /** + * Set the value + * + * @param value the value + */ + public void setValue(String value) + { + this.value = value; + } +} diff --git a/source/web/WEB-INF/alfresco.tld b/source/web/WEB-INF/alfresco.tld index 6d3d9e2a23..cf592f757b 100644 --- a/source/web/WEB-INF/alfresco.tld +++ b/source/web/WEB-INF/alfresco.tld @@ -657,6 +657,12 @@ false true + + + immediate + false + true + diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index d6c63c3fff..296811df9b 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -179,6 +179,43 @@ + + + The bean that backs up the Delete Space Dialog + + DeleteSpaceDialog + org.alfresco.web.bean.spaces.DeleteSpaceDialog + session + + nodeService + #{NodeService} + + + fileFolderService + #{FileFolderService} + + + searchService + #{SearchService} + + + navigator + #{NavigationBean} + + + browseBean + #{BrowseBean} + + + dictionaryService + #{DictionaryService} + + + namespaceService + #{NamespaceService} + + + The bean that holds a users Clipboard state. @@ -495,6 +532,43 @@ + + + The bean that backs up the Delete Content Dialog + + DeleteContentDialog + org.alfresco.web.bean.content.DeleteContentDialog + session + + nodeService + #{NodeService} + + + fileFolderService + #{FileFolderService} + + + searchService + #{SearchService} + + + navigator + #{NavigationBean} + + + browseBean + #{BrowseBean} + + + dictionaryService + #{DictionaryService} + + + namespaceService + #{NamespaceService} + + + The bean that backs up the Link Properties Dialog @@ -883,6 +957,10 @@ browseBean #{BrowseBean} + + navigator + #{NavigationBean} + nodeService #{NodeService} @@ -1398,6 +1476,154 @@ + + + The bean that backs up the Delete Forum Space Dialog + + DeleteForumsDialog + org.alfresco.web.bean.forums.DeleteForumsDialog + session + + nodeService + #{NodeService} + + + fileFolderService + #{FileFolderService} + + + searchService + #{SearchService} + + + navigator + #{NavigationBean} + + + browseBean + #{BrowseBean} + + + dictionaryService + #{DictionaryService} + + + namespaceService + #{NamespaceService} + + + + + + The bean that backs up the Delete Forum Dialog + + DeleteForumDialog + org.alfresco.web.bean.forums.DeleteForumDialog + session + + nodeService + #{NodeService} + + + fileFolderService + #{FileFolderService} + + + searchService + #{SearchService} + + + navigator + #{NavigationBean} + + + browseBean + #{BrowseBean} + + + dictionaryService + #{DictionaryService} + + + namespaceService + #{NamespaceService} + + + + + + The bean that backs up the Delete Topic Dialog + + DeleteTopicDialog + org.alfresco.web.bean.forums.DeleteTopicDialog + session + + nodeService + #{NodeService} + + + fileFolderService + #{FileFolderService} + + + searchService + #{SearchService} + + + navigator + #{NavigationBean} + + + browseBean + #{BrowseBean} + + + dictionaryService + #{DictionaryService} + + + namespaceService + #{NamespaceService} + + + + + + The bean that backs up the Delete Post Dialog + + DeletePostDialog + org.alfresco.web.bean.forums.DeletePostDialog + session + + nodeService + #{NodeService} + + + fileFolderService + #{FileFolderService} + + + searchService + #{SearchService} + + + navigator + #{NavigationBean} + + + browseBean + #{BrowseBean} + + + dictionaryService + #{DictionaryService} + + + namespaceService + #{NamespaceService} + + + The bean that holds state for the Manage Deleted Items screen. @@ -1433,6 +1659,30 @@ session + + Bean that manages the Dashboard framework + DashboardManager + org.alfresco.web.bean.dashboard.DashboardManager + session + + + + + The bean that backs up the Dashboard Config Wizard + + DashboardWizard + org.alfresco.web.bean.dashboard.DashboardWizard + session + + nodeService + #{NodeService} + + + dashboardManager + #{DashboardManager} + + + @@ -1525,4 +1775,23 @@ request + + + + + Bean that returns information on a node + + NodeInfoBean + org.alfresco.web.bean.ajax.NodeInfoBean + request + + nodeService + #{NodeService} + + + contentService + #{ContentService} + + + diff --git a/source/web/WEB-INF/faces-config-enterprise.xml b/source/web/WEB-INF/faces-config-enterprise.xml new file mode 100644 index 0000000000..1c89638123 --- /dev/null +++ b/source/web/WEB-INF/faces-config-enterprise.xml @@ -0,0 +1,24 @@ + + + + + + + + + The bean that holds state for the License Manager. + + LicenseBean + org.alfresco.web.bean.LicenseBean + session + + descriptorService + #{DescriptorService} + + + + + + + diff --git a/source/web/WEB-INF/faces-config-navigation.xml b/source/web/WEB-INF/faces-config-navigation.xml index e9dcf7a6c3..5ca6e3a9c2 100644 --- a/source/web/WEB-INF/faces-config-navigation.xml +++ b/source/web/WEB-INF/faces-config-navigation.xml @@ -32,6 +32,10 @@ browse /jsp/browse/browse.jsp + + myalfresco + /jsp/dashboards/container.jsp + about /jsp/dialog/about.jsp @@ -77,26 +81,22 @@ - + /jsp/* - + adminConsole /jsp/admin/admin-console.jsp + + userConsole + /jsp/users/user-console.jsp + /jsp/browse/browse.jsp - - deleteSpace - /jsp/dialog/delete-space.jsp - - - deleteFile - /jsp/dialog/delete-file.jsp - addContent /jsp/content/add-content-dialog.jsp @@ -259,10 +259,6 @@ manageRules /jsp/dialog/rules.jsp - - deleteSpace - /jsp/dialog/delete-space.jsp - import /jsp/dialog/import.jsp @@ -283,6 +279,10 @@ showForum /jsp/forums/forum.jsp + + editCategories + /jsp/dialog/edit-space-category.jsp + @@ -303,10 +303,6 @@ updateFile /jsp/dialog/update-file.jsp - - deleteFile - /jsp/dialog/delete-file.jsp - editFile /jsp/dialog/edit-file.jsp @@ -327,10 +323,6 @@ editCategories /jsp/dialog/edit-category.jsp - - createAction - /jsp/wizard/create-action/action.jsp - previewContent /jsp/dialog/preview-file.jsp @@ -373,6 +365,18 @@ + + /jsp/dialog/edit-space-category.jsp + + cancel + /jsp/dialog/space-details.jsp + + + finish + /jsp/dialog/space-details.jsp + + + /jsp/dialog/rules.jsp @@ -408,10 +412,6 @@ manageContentUsers /jsp/roles/manage-content-users.jsp - - deleteFile - /jsp/dialog/delete-file.jsp - @@ -425,10 +425,6 @@ manageContentUsers /jsp/roles/manage-content-users.jsp - - deleteFile - /jsp/dialog/delete-file.jsp - @@ -600,6 +596,15 @@ + + + /jsp/users/user-console.jsp + + changePassword + /jsp/users/change-my-password.jsp + + + /jsp/wizard/new-user/* @@ -790,24 +795,6 @@ showTopicDetails /jsp/forums/topic-details.jsp - - - deleteForums - /jsp/forums/delete-forums.jsp - - - deleteForum - /jsp/forums/delete-forum.jsp - - - deleteTopic - /jsp/forums/delete-topic.jsp - - - deletePost - /jsp/forums/delete-post.jsp - - manageInvitedUsers /jsp/roles/manage-invited-users.jsp @@ -822,34 +809,6 @@ - - /jsp/forums/delete-forums.jsp - - forumsDeleted - /jsp/forums/forums.jsp - - - browse - /jsp/browse/browse.jsp - - - - - /jsp/forums/delete-forum.jsp - - forumDeleted - /jsp/forums/forums.jsp - - - - - /jsp/forums/delete-topic.jsp - - topicDeleted - /jsp/forums/forum.jsp - - - /jsp/trashcan/* @@ -887,4 +846,21 @@ + + + /jsp/dialog/container.jsp + + forumsDeleted + /jsp/forums/forums.jsp + + + forumDeleted + /jsp/forums/forums.jsp + + + topicDeleted + /jsp/forums/forum.jsp + + + diff --git a/source/web/WEB-INF/faces-config-repo.xml b/source/web/WEB-INF/faces-config-repo.xml index 1fd9dece11..e4d3bd38ab 100644 --- a/source/web/WEB-INF/faces-config-repo.xml +++ b/source/web/WEB-INF/faces-config-repo.xml @@ -124,6 +124,11 @@ org.alfresco.web.ui.repo.component.evaluator.ActionInstanceEvaluator + + org.alfresco.faces.NodeInfo + org.alfresco.web.ui.repo.component.UINodeInfo + + diff --git a/source/web/WEB-INF/repo.tld b/source/web/WEB-INF/repo.tld index ac35d51978..02c03607b6 100644 --- a/source/web/WEB-INF/repo.tld +++ b/source/web/WEB-INF/repo.tld @@ -1514,4 +1514,28 @@ + + nodeInfo + org.alfresco.web.ui.repo.tag.NodeInfoTag + JSP + + + The nodeInfo component wraps another component, typically an + action link, to provide a floating pop up panel containing + information on a particular node. + + + + id + false + true + + + + value + true + true + + + diff --git a/source/web/WEB-INF/web.xml b/source/web/WEB-INF/web.xml index 0f53fbdbb6..45e03798a7 100644 --- a/source/web/WEB-INF/web.xml +++ b/source/web/WEB-INF/web.xml @@ -16,7 +16,7 @@ javax.faces.CONFIG_FILES - /WEB-INF/faces-config-app.xml,/WEB-INF/faces-config-beans.xml,/WEB-INF/faces-config-navigation.xml,/WEB-INF/faces-config-common.xml,/WEB-INF/faces-config-repo.xml,WEB-INF/faces-config-custom.xml + /WEB-INF/faces-config-app.xml,/WEB-INF/faces-config-beans.xml,/WEB-INF/faces-config-navigation.xml,/WEB-INF/faces-config-common.xml,/WEB-INF/faces-config-repo.xml,WEB-INF/faces-config-custom.xml,/WEB-INF/faces-config-enterprise.xml @@ -155,6 +155,11 @@ org.alfresco.web.app.servlet.CommandServlet + + ajaxServlet + org.alfresco.web.app.servlet.ajax.AjaxServlet + + axis org.apache.axis.transport.http.AxisServlet @@ -205,6 +210,11 @@ /command/* + + ajaxServlet + /ajax/* + + axis /api/* diff --git a/source/web/css/main.css b/source/web/css/main.css index b9ae62af06..7f2e713ba6 100644 --- a/source/web/css/main.css +++ b/source/web/css/main.css @@ -488,3 +488,34 @@ a.topToolbarLinkHighlight, a.topToolbarLinkHighlight:link, a.topToolbarLinkHighl { vertical-align: top; } + +.alignMiddle +{ + vertical-align: middle; +} + +.tableThirdWidth +{ + width: 33%; + vertical-align: top; +} + +.tableNarrowWidth +{ + width: 30%; + vertical-align: top; +} + +.tableWideWidth +{ + width: 70%; + vertical-align: top; +} + +.summaryPopupPanel +{ + background-color: #e9f0f4; + border: 1px solid #999999; + padding: 4px; + -moz-border-radius: 4px; +} diff --git a/source/web/images/filetypes/odf.gif b/source/web/images/filetypes/odf.gif new file mode 100644 index 0000000000000000000000000000000000000000..d5bc5e0083d9783048556669f12141f3f47d86ce GIT binary patch literal 1019 zcmeIx!Alfj7{~E<#n9ADL?bB|mZVzJXhUe%EpXSRav-WXguREz27(xa>@5gh2^ZgV zgLf_IJrul!CU10TphI&om_tNEhZ^wEkco2&*61*m;8K_Eng5|}Q3n_(ELMdTc0#4hKQA#RcNekH0wpEm+ zEMO}*ZAUr4wW4gx29D(b*K&bpM>)0wT-ybn?Rid=>$t81+wQMGEVRznD$|NYx9koa96LueND zA}IPNP~&IRo%xffW4rpVx0aKGx%sz4WAWjM`Yj*2nz!#rPxPN`t&d-tFHDH(cMav) zc>HN>);?e=!e%GBgSUqCNE?4%DiHPv@mFN*)Gj)p;olf-w3tp6$QjcRn13vvbbd z9$k3);9zMwnNC8Ir1>z-#{)7PXPqJ&7kQ`5i*iWHYFt(Ysp_I8O<6Y;X;@8I+c4I! zmbIL5B3jN{szUHCg40DvE(wTwAb8U?x=0}j2msmiC2yo4)T6f)kkkhSECpTwuRyS_ z(M5q$ptWlHilvHWO4LfW3WVyS6@AjE#ZUv&AhaU%oKR3BG1$%`&yeRR$PmRCWr4Cp zs1Z0SB54I`s;ZmlV$fK_QzOXGNKzQ63^YbHMhl~*(O^&-)TWCy)>@HTky%M{E5{ZJ z3#En1s@m$-YHqc#$Sq2XU{P5^v^8k&Ok3;dSVz@6G3!L?BpEoFJ0N4HDyM3P+@WwN zogv_ib{3sA-CP$>$9by3i&-yIFEcN552=TNhs*=rhh7z4m0s0eS6(xZtw-)rc*DJs z-hj8tTl7wQXS}m_R@!cBm*4}50nz}2pzDB5Ko+nKhVWozun?>Y4uYeqgTvrW@UENd z5<`qJNunA=okg8TJ&ZVxSVSx%R?*baw9)eDAbJyni_z1>|4jeiiC&UyB?l5p_fI4{ zwi0;dQuD`Dd*8{kyL;1f>))R^_VdDMHQWBd#N^(o(e`}j`}-e1Ha~iKe%oEWef_Ny zUp;w~&G+X{Z>-Pld+^>}_pjY^{-Gmx@0@w;*Y?&AYwHhJ=U?1>l)cL@Z=IcdZk0X% z<@$C5Qe4?P`n< literal 0 HcmV?d00001 diff --git a/source/web/images/filetypes/odp.gif b/source/web/images/filetypes/odp.gif new file mode 100644 index 0000000000000000000000000000000000000000..a8bceca5aef78a4711fbc864a92802876c19eb58 GIT binary patch literal 1030 zcma*m&5Is29KiAHb}hT=;Q^^Wz9A2`wF~uS4oV-izKm7rP!PwWbi6$4C?dg?l1dkY zAaz8=c-Ru`C15E;RGO2->TYAJ3n^GPAk?6h4brL+3Qg^0s34EO@h|YphmcGrnbSP6 z^YLxNxgP4F7NM*tv!WV;vdTMkUe!eh7d0*cCKVvG#-t_`(}sYCQN|m_8W_1?Kmf@p z=8zB^=2D7kR#Zd5VN(cLN+pz%=MB&F<95}qins)4FAg>%)^iZdm-f;~uUrHv-J zrj_PY3$B&aT}B&VwY8@1n|fey-{65ExuJ!jmEpt)W|TBt)>vyRWNTz`-_p`HwdK@G zZk4b~S_9WW&N}C6gQl&+~9s~y9R6DI(5iaRZx(asoWL3h+S?|kqz z@)%5e-1B(WxOnchmC5tpt$**{2N(N`a|b5(f3vWQ z|M|zw%NzQ4?Ys2m=e-ZNymhAk_ZRbP#~ywA$kGLWXE-|d%hxZjE&VvBixbE9-g@EE z>5rca2VdE<{NkDH)o{z%D^sgK-}wB(U;c8w>(`~bo7dG%_ig>*(;dx6*Iu`PpWHk; z-OQ}WYYzQ($G20LXP=(gee|It`8)2h9sK0>7q+}{wchm9XS+XnX8X*BVzlX=m(~x? Yt}Y)tx$n08@aU1_U+&#MF@f&?7yAEW<^TWy literal 0 HcmV?d00001 diff --git a/source/web/images/filetypes/ods.gif b/source/web/images/filetypes/ods.gif new file mode 100644 index 0000000000000000000000000000000000000000..0758aa2aafd06ae8241de7db11b3a002e35ed7a3 GIT binary patch literal 1026 zcmcJO-)me&6vwB{Mgt-&C6tgp#P|yrjj%S_UQ3~FFtxW7>V1-1EKRS{A491yP?SMo zmr+qh!FH-u2C?FR(i}l>LJOV}5XV+w2wE;eY^rRgY_43YT&7&1JX3x`A=AcctFCbTT!Xy~j13*3UVpe=y)x%J$7VKK3x zZ3Ah?hSbJ{-l*d>K+6HCciuSf9CC-!h17-2g~G*-i>ZrQ9U;7>Ab1ZR0R^A})PM%i z0s^21Ltc20dDjj&6G-AAGPrcprj~#z*j_sM|FG1JE1;nTSzi zv={*+Vhk7~mIh0QC0(Tm5ov`OLkXcIEn`g?%Mi&|K2{-CF;-PsQ$sZrsXU;viWn1#ZEBn9bZ9TU<`N`q&?^jM7cx>sb z-uOSK{+zzJBP>6E{kyXl77iSGduhwwmF0yypE=k~&n)hnSvmg0Au-iEdtv_Ctw*lz zh1(zPUZ4N@)~m0doVons_~uPFe}8{^)4d1({;7Fs_k8#97k2ed-S)wexew3p?B2h& u_)h2BFIU$-zVGVsxt&kRt-sz_d-%DF;*ZToPi$yTi{2eGf6d*+cKiqGNMo%4 literal 0 HcmV?d00001 diff --git a/source/web/images/filetypes/odt.gif b/source/web/images/filetypes/odt.gif index 0371d01493944accb7dad38b6a504ec52cbdcf9f..e89833a22d7241911697a4f86f3076ea2fded37d 100644 GIT binary patch literal 1010 zcmeH`!AliE9LHDFe1Xwo7C}<8D;`Q;F3^A z7$-~+$U;#rD3_EgDkOy}L7#EXxL^X5OeiLOE+m(r;*b>>2qA?8l~ABBVDUq#QBr}v z^ua*F7=%jWD<2FL)F4t}0;X}2#c7&o(gZ@9C0UkgvJ^sA$uyO$0#+-UYNZNpS2f$!?f?Ai59I&U)#xKQ zp&xw{MsCBXF^0Fk*Ueb8Wu;(t&-N6D+Dc0wuaCDhn$4X{^EdbGXdQa~Y3kyeox8@3 zHf#CA!1&&=8;$)dbJvOu#)G6+JZspTKUtdW8XGw^`NSOjnHxD;YMSr9U0YwfwSHM0 zF7NOD^7hf<>%y7b`Cm@bf461eP`mYN`u9X};$8H4bK&XN7qzYX)*p^eeS2B1?pJXJo@vARBU L>0novVVwI5+q9)$ literal 1024 zcmeIxPiqrF7{~ERT+AX0V-GU*PswUq8>od)BppSlqo#4O)b63!RElv=vKMtI2&<5o zg@n3DtP2L6OB>fy10K5Q!G)-C!6G?E4^pC4JXS$SZu-QFZ=xT*JTKq}&&2uU7|mdW zQ5zwd5Sb`giQ^bVaU5bqi4m$2rV*A_;#8qbp{k;$W00oDnMzfSrVXldrlpx~FrBNA zVQRXe8C(aP>)g~W#{h7hsv$hyWpdNvmc?y{+ky+v1hz08VY;4WSvC-^?Ya&S!f{;z z;Cj9bs#VwXtH5t~!1ukN={1@@2m-&c5r9Tl6Kr(-09)-X(EjJow(SM}FEETi_ZN`- z9aYGC6w0Cfqw}vW{R$@^4B^UJ`O0{Bk1`qUn|*U8RVVwF&aQ>t2KNT0XTD{Lo-d$C zYBigy?_77LEm4f3TJFhY>UyiRqh30YILySC&0D=a}KLl5mkM)>OV6b(v>0q#=uTqGVOWQnxv)n~{C)f7p+E=8;cc z?_V!D>mJM7hBghPfszoUh0!t_T;_z!z(CMSo3qjeS2_Wt62S~M*x-Z>Fk(P4vlBKu z5i^XK!A5a2hTCAo2BS6vwV{{|oEYImP$!BxG296@PQWMzV>pZh1dNj~K_V!IU^s%~ z2tgqvh2jKCQW#EP1c{L(M$tG);S`0_G)^-FNfIPQPykKPG{FE2Nzo(?FeKOvOR@~f zf|sLcnxYwsVJMcRz{#<+7(+7vOS1q+a~vbaGAzI`;N(I~2;f;Uj^%(58v=Ni2Lw(m z#DxH!;{kyagpe2?;`tERLX;O1cmas=Q6MIWMTIC36JkI-Di({zfOs?xBw}LmSR6>i z5{bB2A`V6(nGj1RlE7+GY&E&Mx(Y$y`M>}63us?TB@i?S=^>E#PeAh5kZNuBf_B=Q zQG9vq*jWpiuZL%;E@(j5v!jkf;QY%E3 zHwHQ!Z#^1rtnU6f*y0a|Q>!Z02(vS3L$|)Ik(q{5yro$gdFm}K_cuQdoE>`BSfpDs zK-VAn+&Gf%-Fr^CsivhTs2SkD_blhR!yZ{~rPH6;mU_ajRO_32{lV78pGHnS^_zkn zr@z?Y5R3;fOU96DSLdYts{f{O#P=#F!E{;YHq|ayANXc&pk!y`Iepn3M3%W;nO3GE ztb;ddn+kUKP4l-#>p!{Ja4ST}vkNn%zpn8VZ*A6Z&V60po_DY6kh-ovZ&VYUYI^70 z{Dm<|J+{aEu;_7keoDX5M_=5Zw&PW+Oxsr)csN-7dkfmcd3q8l*o!Zslx|H4)(Ys=eP3|l(v0E zV%4DeX7Bo@7p|ELy$^Cc8K^E`wVcS&Tvy=Zj(%-_;kt$khVJj?FH%n?E@>OumZg&1 zamD-wFQI&*wn%SFwSh}pFDr|Njp6jyACEhHm%WR>*X1&R!?U;ksQWKT}S1*24)i7)9`{9>$ z?%Ua^twGCqmo$*LhIb9uD*j2kn#d}=SrL{Wqn7HgNmARris}_@FkI34Y#J(?UFs|7 zg&s`If7r6*QJz?A^QrNbQJ<>hiv20H?abb1w Zw8ogRJKQys*Ar)xX)*juRSpF0`WGM)nZN)5 literal 0 HcmV?d00001 diff --git a/source/web/images/filetypes32/odg.gif b/source/web/images/filetypes32/odg.gif new file mode 100644 index 0000000000000000000000000000000000000000..f4dbaf33ec93b1d1f935aa7aed85946659f7c203 GIT binary patch literal 1590 zcmbu;|4$QV90%|NQTe(7f>wvv0)mJGiVm-e3l^-Upws$;qtS>hKe%;qrmYKET?AH8 z*olBOI&(M>Z!)%X2tLtGE;=v=Li<1zZcg!ufbsUl<(5cxn=#&=^IzEedF7KQpL;%^ z-)?J(i8Soj5?Vqg2))Isx7ZAr)n-&Vj5dcw<+M1QR?O+PIo%G-?R9uDpVRAeV?N4@ zQGOpq`6xf-rzsj^{50*ym0@T#42>@gOS2eYyatB$sSPzO!(xB|fc5EE+Q%{&?%}sM zfW>{l0ZI>O2cX@6q11*N4saacdCsTfC_P6RImXMeehx648lJApo}k zd;;eact+q^fd>L)1;`6(kbn?k^oTJc7PBDMhJXVBCjxH7c@ghNJdJn;K^j38L4Y8K z1dK-lM6ah267fMIu9C=Pii}=lF@wljM1a{u&Mk6Y5z-=LM97K)21J1u5fqW2&Z&{` z5hYw@iOG~$y~G+N)*=DD1Pl@|N&w%j66cUOr^IrpQ1q1B1+aW$2S3B}2a~V6==_837q_vIt}mS6&vOED5qC zs&i@-Sy2>%P&k9a8x`K7@Ky!d6zEW(Q-N+p@G62|L9`+QMG_QQR1^tM{LkqA4GSTN z2gDizNBt*=@K*$gm`JZ{Ok8a~S6DOS8;V}KwrZWWaPyX)8qM17&dP@FG){JZnn1vDjMh~J#qCBRE+)n zhA%@_#`$A)g`V;14rADSkH5Ax)fBi?@!t2FHchAP>~VUm=AoF{qWZ|tu$jr4q}3Ce z^kc8~4laK5LX1u#J*2kz`dBe(zJ8#leD9qdvsZpw!JDa53K8GYw!zhNx-Ri(c#275 z55zTA{ajoX%xxbJnW(${!EV~!+HW7tZlBAuiMxWgH;%r>rrTz;MtL{A}V+@b07i}kJ$icLx zj$59Qw9B4>(w3mFFD9*7b1!B+|0E?qd*CnjvZgZoos1vm2B`Hd+WRHh!yk28RvZ?V zCYgc-u91~rty@%<-O{6vZ2QTxYiL=+-4c`OazRRiu5DdWWab&V`}ehv{L}T_uX(&P%+8tCJU@10u0GUqBdKDdF|{hGH{xyi?!$(2 zXC~en$rugXJ?NOXZRU8gt1|Qu*Iqps%<-m`PuOSbLyIF zM@IAcL(jL7<)3s~mX?245Mp}cxo+!7*0rhL^l!WD)avGmoeSdkT}=uxT_$^n#`@9* zh9}?OcjEYp&$>G1FL6}{hv#Wl&YF{5;VDrm_G^FsJ^4mOam>yAu_>jxkHr&*7f)#> aZy6)fr^ag|eM=7hGkvT`yQ7dGHvR{WqJj

z$kZB+mB@69G&YxMJdKwwoysC_k2WJqOuP6&`dt5le&;jKJkLJ+Jp0q; zx)x;TtWL&~F$2RKZjZx_=O7;38Adp9!W~As3DSd*6pm0dK~e-olQcsi3`?^d!?Fw- zIi5v$MBr$WL-9O^=7PZElXyIb=g=n4qopA7q9}N50`3qfj}T52&=XM-ahpguMA9iT zgvha?z=>!NB}t+rOO#WhafzcPo|8mD3MWf4qDYD&6IPk9$)r^#Z8GJQX}3({GDpcg zD~p00PLUNw!7+uv6w<2D9)%$kj#dOt5qU)v6d7HE0tx_tzyN6mq!o}hKso^B1dInT zIA96Dl7OQCkI+EmfFuA}0+UIaL~QtBglw z36-N%9-&oPnOH4@V(vqm{I+NRMt8spR$x5juh7Qr=+&^S`#DNR6V zO<**M*JMP{6iEX>Ll=dE8bowRVvsUH$_yzhq>)LGc0f7@G7iW%A&a;n>wzo|IUMp7 z6lf?gP^6)VMi$CElm)0DB2**@WT*nDsStf2oDOxw&?%EnnRObm>Wo8YksO_M>a1Jm zah)f1fzm}<7g=5Aby?6AQ3r^m16kLAuBkfIbaY)fLpP9qgL50a$KY{;Ck%--WX=Gh zp#ejO26`!6ztP{{k750W-v8eet^Q}Wmyr<|){A9esPI35nO>3!_S3D$=YqLPBNNWeiBTixMVg|An_fiZb)Ry2^Sw32 zg|5ofrROth${#iC8al%KMrf*iUG35prB@56LS=B)lJj?3`&`3@j2J&>ZJj;B=PPhk zj4I9x9=^SGNnXLrI~&@Lk80iY_2ZqZeOUSDUs%6-#Vu&w)N}9k+oyU*&)YLRX}Bpt zdwww5>{ye(Ki9LOtn|f|UBwl`mHyOw*Yivt<;{-`C2u_aXt%9lXDz7c*&f$oo4Y(a zp|sI)H!Afq7Wcu-pG!KDnb>X9TK1+5kE?vQ?GTfYbfI%9JM)k2M904D?y?TM>+eo5 zyR@ZYk^P?kbjN}0KL4^A+q`|hWd2rG(aAk9J+Dro3kJ9|@0N8ep3%wNZaK7ecLzJI ztL)FNO8bs$O%uMqU%fA@JLO;~zO4K5`w1tk6q{a@H?Gk767} z&R35!gp}gu6S*JHuS)!KdvM6~#_VZLqZ_%RziJxqRQoML@zw)LuS+A_n=|Un7osgE zdjrE9KRyjEnsV}J-~1Xj=HimXRVJrDU5>s`X-PX;9kQSD)(@&YGiS@17)xPZR8qy} zKxJmboOIScF+iWKhnM;qFQ?|0EJ~!!)kD&+nl7-Go?c&-y}r}8XhKhY-&uQN{&ZI& zVfHnrAM>{lO$>OqS0)6!lbhm4Rkd%t9-rTsn^;)4Y;Q_zQy?@pvG#uP6xO`#S)}F3 zd%-ukg?+BHOKAar>hZ|8F1FUyRn2c5aVI}&boRU;mA3!kx2Ewm-XlXN*PIE2;<8LJ z<)N+qo4dzu8|e%EzRqlmjQy+VKxsKn&I8}vg;7Bq;_^h1UCC$$F5)r literal 0 HcmV?d00001 diff --git a/source/web/images/filetypes32/ods.gif b/source/web/images/filetypes32/ods.gif new file mode 100644 index 0000000000000000000000000000000000000000..0e3c81775c15163ed847b065504f1ba8a6503191 GIT binary patch literal 1590 zcmcJO{Zmv`7{{+GBJvU_MnI?wi@Yhii-NmGaYNNc?+C_&Ai88kRgo1SE3%9^ z84EIT%Y>DQS5_Ue>XubD7@;VT29cs51tZKOEFvr+3=oD0BZL)%F(MoyJR$-jA|etZ z01+9ftP%t(7%Et%rxi>+Q3zCsq7b5}Kv9vR@xgWwf(fE?OsG+@Dq$636=4-)m0(rH z8o-*2HF}grC@NhUBlciK?rru4_SbO~;x}G+m`uqfI@a1&9{V zUl7m(DsAX=8=!tjAJPJpp`pOgNKk@|42@7;$jIo(=;$cJjK26%`~Q*rPskXC(V3YH zCHN+ou;&b(@N~F^qlZ>cn~LFU6fLn9Nq+>p7YemDEw`ueyHEY-bq5BX&{+vOWSb{;;|>drBmt!+O5a^mLMhwRD%>4+6PxO_Ba z#^brm3alk%W%lZ{qqmyIoi>e$F)lf(*Vbjd37U-ycJw@ItLkjsxxjR-&S@&mm{+{1 z;PCVo?JLjw-&CDXdCq!qMmvr~cDV3#5OMADqdypmGi!^5TF=f020 zdw1jh*;mRk)0(o^pV=9;g88#`)$d_osio zE_`>(b69tA(S(8gy#BoS3VU~U{WC|@)cjgcM(c&}LlZ6WWeq)9TjQNYQ(re8tVvw^ z)7`Y_8|?nVsY}KAE>}&N(U5+^{A9`8wVn2^i>a3x--K7&eqA4(u+X{4^>*2YU()LB zvGsAO3r)kFi`SWlJD<9iIbHM1s+}_$tcIw$Yk>KWtNj%#Eu=rcz%VzxynJlv!V7Gz zsmIkJ5Aj}|KZpE1LTfKc>n+a literal 0 HcmV?d00001 diff --git a/source/web/images/filetypes32/odt.gif b/source/web/images/filetypes32/odt.gif index 34e0bea33d77b166e7a0c73d10f34dc0a1863449..b920c40f0b00ea8c1cf8ff6bdee5fd79a7539f43 100644 GIT binary patch literal 1501 zcmeH`|4$ob9LEc5X=UX*)GD*IrLsDZwcwIf%~D!{wl*6p$slK3Di?uyM1ce1ykPip zEG!A&jSUz-SQg3fxxc|*edU!W@Av!1 zC;1c`i;ikOkaDD)2!}}@?ZUGBMKnMyU7=!|G2qhq} z;3SNoFp9w#4r2t2kuX?r3c+v$ClL?`3dL{~Cs3S3K_+R8ATff%2pS_P3{(o}!U+N= zNSp*xI7#D_iy$e20@4J?G|)|w6iESTk_Ng+u(&)F3r*2L7v%!FDKNS{G>eON0o^pH zZieXLhd>B#hFLblo508>OJp+w+>5a6MfU#Zzy5&i88?bOf*kf? zZ-OIu&WRFm6Lk~(IO)XVxc+L_OL>(G*FOER{erVqoPVlbH9mPh1=?Ed&8+H{7k4h& zR90!*H-tFbSbt0Jy^vo%Mh*`QUc9Ys-k2|UEP30Hsd#?jtt;Jkt{zKkd^U2qTWwn>7@t#>Tg;j9;u75a}Ar)#Sm=HhdY8_pC|{gHMM>t9f}`w}I; zmklTjM)XDeLQ@)V0iK;HHJ-RWuU<9GIt~Zw^u`f=t9A?_^c^Nfp)mIJKR>ZYabroP zh#Ma{^I*D7rdO36`c1Iw{KuB~WccQd8`SzG?yM+5R$a$P&?VWF{H}4?p|C0Q3>nSb zihH$xCi$q?BQ+=a@^;m-p*=yjBgj-nh~eWsbXY}Z?~jWS7iN;D zK6*%BZt6(l@#dC%qFU>rp~0>=g)xfvhTWHRcJRTY@5a9Wy45ZjtdHU+9LXIhq-q~+ zO~}15eY_%bs!jWH^{#DQC~023_EQEoJttK>UQ&7BJ#m3SzSy+>+xiuQmdBbSe^PPxmP_YY^rDFKGjyQo@Ye)&fe|YSv@T?@@PS=KIzpd R4s%D#fBok`HlNFR>tA4Oe(C@K literal 1576 zcmV+@2G{vVNk%w1VITk?0QUd@00030|Nr~@{O#@T>FMgv(bKxX#Zy{e!N<$T%FOop z`}6kr+~47Kp}caPw{V)YZI-WKgqku!OrXBeoVm=Iw#b2*sD+%XhL@t3skDlkq`1x6 z*52dg?eY>NE*md8G)q`ANK{^emvDoQhMcIi%h;T+y1LNauEWoksIsWM$HLa)zti8N zw7xYuJ$r_XUSnply1&83$;Hae6fiy$EjkS!C>AtB96?kYKT#MsNE9wS4mV6H9;swRxVItF;r$ROIj#9MMr3P zM`m_PYI;m)cSc}sPHA^td5BMAZ9h*}Y=)FUQCUS(T5yGsa)XRqYH?6pVuzchcZiWw zUu9lsZESXXlAfe|f`z`o!5KVF4k9ZYLsc3+PZu{v9Yj|VC^H#4N)|Ig5G5}gJWLZS zHWe#19z04YPhu%hV<${rCP-H*PhcxfUMNUcF;{6dT5K;+U@AyfI9qHxUvMx@TPZ?K zKVfk_T4*^`U`uR!PHlWhWpYMhZ&Y)FP;PuPMNLRyY(Q3EAS*CSWN=q>flFgj*==iJ4#z(QetU(iH~M-caor{Z+U%)l9rpL zsiCW{!^p}}SzMi~u(-g(pRBO6zr&ZEpRKdCr>?Ma?+s4PosHv%?rlzE&rJtanot~bS zmzR-}l7fSS{{H^_{QUa*`uX|!_xJbo^z`!b^6&5O>+9?1=jY?&f$jHRR#K6G7y}iA=ySulyx3sjhva+(Uu&}PKuB)r7 zqN1Xko12xDm5+~)jEszliHU`Ug@Ay7c6N4dZf^ho{{R3000000000000000000000 z0000000000A^8LW008y?EC2ui03ZM$000R80PP9H)aOSU9Bv+=qLyt~I(Et0v0HcU z95H3>dP9ez=-hZi1I>YW z#;^)VS8SX&VcsSafM+ulh$Ns&jq&7S9M+5Gx+SH??c6$d@#3uu#*tX3P6-HLeTH?O zI&RdSU4=$q+qPlD&;^sXvDhwNSi=whg;&lRw8_w-5x92En>=CyajhHrD$5)>JRrSe zma>{N@!>@ijWF;0Vvj7~1W?WugXrMK8E*u^g$608P{IiqX1Ia^ST(Z^JhTYZ3o))l z;ztiZ^q|8W5J2#N0}aF|V~i6l7fw7jv4RK^KN$2z6Eg-WV~s-%aE>uHeepycJ?2ou z78yn8w>y_=1|Xc1J5iRwXz5wJ+iSzBV&#!4LQl!l*u7> z^oRouFEHchpMVC+Of~G>ViOjG4AG++K9I1%qmV+%!UD}y+Kd1MhR9JBfTYNV8*n%v z>ZqhTK*2MpJ_F4+XK}QOBuw=Gz=oSfJYegsxIR#UfC3IM4vrjg!pIV79Q1}0C?u=w zvM6vc&9l>3la4YuN}&f1IH*B`76f$b?YH0(APhUl*fdHaN92&h89Rhw&Aaf%E3Y-( zv{Q^tWGI4%8fv&vgBLCZEbzcCedEr(9K|xl9%r1PLk$v`Ao0W$PuxNQktKtSO{Pqt zgd1)={6PdHmu#}h7j!dBJMY*8iz9!8tiui-h+y;0IOA-=H{r0;>PBWUr(n=fP%{OyJH9{dp%#+T|le$+G>vrOjMTC aQ8o@bJTibZc;~J6-qnZ&W2is@0RTJijOKR$ diff --git a/source/web/images/icons/configure.gif b/source/web/images/icons/configure.gif new file mode 100644 index 0000000000000000000000000000000000000000..374f787193011edb84c5f082f6e51d33737e4c0f GIT binary patch literal 1008 zcmZ?wbhEHbv#qVO zv$LzCV?tl=?3pv?%%0scWA%gy3uaE;KMRPa?ccDVVZ(}s1q&7|U9x1^lBLU+E?vHC z*@~r0SFc*Ne*O9l>(_7Ev}wn-?YnpF+P8P_tZ4_Ptv_z8_<9x2FE*U2{ zlGXX;`b!>FR9;+kc$!uDyDKw=)%j%1a~y0YCO7xZnN@IagQLJAPZ=TAQ!_Rs9_C`< zaGQ1@a6!T;Ce{#zkPZe$&)KXgclKBoDY3J1@V0CS+?;k+RK!LvN1{QQW0p{6-+`?L z3mKS2?a$nJv2pwR4t=e%4$Yt)2Rc}y!Y(idbHULqQL Vay7s#-N3;wW0F#kprF8D4FHSmZv6lN literal 0 HcmV?d00001 diff --git a/source/web/images/icons/configure_dashboard.gif b/source/web/images/icons/configure_dashboard.gif new file mode 100644 index 0000000000000000000000000000000000000000..d79e1a233b4d5dc65148527de1fbd97c903df36b GIT binary patch literal 998 zcmZ?wbhEHb6krfw_|CwvT}=FbWYnqr!dnT++mbU6q!*s)nY6!m_PXY2JEyK(xc*@F zqEjY|?p5!+XSMF7+paGTtM0jPcp7&2Z|MFX!FxVN9{65<;eY9|k25cSn1A7g^|rU} zdp<{=_!GMCqwktq(MP^VANmr$>s8$GU-8F&WE}liaPeQ!k=K>yzBU|s(0|~X$I)NG zXa0wt`ya9EaoC0{b1uIsI{YB@;GL3lS96XWUvcD6*!IP(7dEfkxh3~dQ_K0u)r)E} zcEmLuEy-FCS+}}i^_h7Vtr9L1RN|+4R;*0Y%H;8!sOsLYTD?84ZB23ahDxn;PTgD{ z{Y?IVNqP*lg+XR+&Ka_Hr7>Sl2J&r;GzW-8p~+OjsQ zbc;vtj{K=x>J1AStZP{}$5(%k)xi>m-D?N{Sqk z5#K2-wnIblp0UnjN1M|gPKV;655~tF%Fo>+$ah*yxvOBcy4^awqVL jT8EG}vm~RI^OH^oXNGGGg-sXyX0>Fs-HDMEV6X-N$+sry literal 0 HcmV?d00001 diff --git a/source/web/images/icons/configure_dashboard_large.gif b/source/web/images/icons/configure_dashboard_large.gif new file mode 100644 index 0000000000000000000000000000000000000000..336f7967ddfcc879f6ccecececb4bd6a8cbe9233 GIT binary patch literal 1488 zcmV;>1uyzXNk%w1VITk?0QUd@vmqkFEib|^FuX1==xJ;FcX-ZdYSVgr*Mf!YijdNi zmfwhw)0m{vsj-}#uCTMpgR|C4vExp*=~cb)RlDs}xanBF@msrY9S;F;M!17(g^k2sIU&Z!b#Pnds_g%p7VZ`)f$oF2o z>1WCKUby3Dz2kJl=qaq?GPCG5ujE6$?>L^vM!xYvqRLRd?N-F}ORUvWy5m>0+EuO6 zXvgl1&FQV!=~K)3R>}2O!Rlno^JurzjKkQg%+*@9%5J>LdceVU!M%#iv!&OlnZ}l* z)|h*$ZHcpZU9>k=t}0QcC{(K|QmHCpyEvKQcdO!(mbQm5dI%|H2s3aIGHnqvZxSt!N zqG3qRrk|=349FG_trZcr7!$e~6|oo;t{4=t8Wpn}7PlQ3u^SiJBpu5k8?qi5yC56E zAspN(A;lveyCNOLBp<9G8^k6cz$72PBOkOO9kL-E!X_ZXB_O~hAi5wrlookx4}75g|Wf0{?3_jTpCkw#Xoo|N)CX4g| zh624@gXuE!$ifLFihvqO9s;ecbIdl`RI^L~r4-W0W{^zsj{?DPqm4Ds)Due?iSYVr ztn!GK%`yVyx~pb=2*gV_v|3{hd}Ms8$GU-8F&WE}liaPeQ!k=K>yzBU|s(0|~X$I)NG zXa0wt`ya9EaoC0{b1uIsI{YB@;GL3lS96XWUvcD6*!IP(7dEfkxh3~dQ_K0u)r)E} zcEmLuEy-FCS+}}i^_h7Vtr9L1RN|+4R;*0Y%H;8!sOsLYTD?84ZB23ahDxn;PTgD{ z{Y?IVNqP*lg+XR+&Ka_Hr7>Sl2J&r;GzW-8p~+OjsQ zbc;vtj{K=x>J1AStZP{}$5(%k)xi>m-D?N{Sqk z5#K2-wnIblp0UnjN1M|gPKV;655~tF%Fo>+$ah*yxvOBcy4^awqVL jT8EG}vm~RI^OH^oXNGGGg-sXyX0>Fs-HDMEV6X-N$+sry literal 0 HcmV?d00001 diff --git a/source/web/images/icons/dashboard_large.gif b/source/web/images/icons/dashboard_large.gif new file mode 100644 index 0000000000000000000000000000000000000000..336f7967ddfcc879f6ccecececb4bd6a8cbe9233 GIT binary patch literal 1488 zcmV;>1uyzXNk%w1VITk?0QUd@vmqkFEib|^FuX1==xJ;FcX-ZdYSVgr*Mf!YijdNi zmfwhw)0m{vsj-}#uCTMpgR|C4vExp*=~cb)RlDs}xanBF@msrY9S;F;M!17(g^k2sIU&Z!b#Pnds_g%p7VZ`)f$oF2o z>1WCKUby3Dz2kJl=qaq?GPCG5ujE6$?>L^vM!xYvqRLRd?N-F}ORUvWy5m>0+EuO6 zXvgl1&FQV!=~K)3R>}2O!Rlno^JurzjKkQg%+*@9%5J>LdceVU!M%#iv!&OlnZ}l* z)|h*$ZHcpZU9>k=t}0QcC{(K|QmHCpyEvKQcdO!(mbQm5dI%|H2s3aIGHnqvZxSt!N zqG3qRrk|=349FG_trZcr7!$e~6|oo;t{4=t8Wpn}7PlQ3u^SiJBpu5k8?qi5yC56E zAspN(A;lveyCNOLBp<9G8^k6cz$72PBOkOO9kL-E!X_ZXB_O~hAi5wrlookx4}75g|Wf0{?3_jTpCkw#Xoo|N)CX4g| zh624@gXuE!$ifLFihvqO9s;ecbIdl`RI^L~r4-W0W{^zsj{?DPqm4Ds)Due?iSYVr ztn!GK%`yVyx~pb=2*gV_v|3{hd}Mft9Dc)uy}DrMlCoyw#_>)TX-ArMc3o zzSgR|)40pyk)N@TovxLmw3wx}m!!0rrnb4p*0{saw!zN1!_U3P)4aygyT#Ga)Y)i~ z!gr(AUvr9ahoEJ6j%$9CYkiV!f0L%X)ug%6qqxwgyws+<)0n2Vm!-9tr?;G`xV*~Q zw!+W4#nHLM(7ngf$k5rw&)CP$*UHk`$uq|4IR%GBC` zlby`m3J@bzE#?FiT7gH8KrNG%_3QNiEvj+rtV8 z85=$j92yuS9T5*d7Z(;5?(gpv^!27+Rb5wDR9047J+wT@5e3H$9Xz1$kfI~X4jnqC zOo@00kHw1^Giuy;@eTq4AVZ2ANwOqJ1YW>^@xrp@%9b!=%2bK+zyU9U1bMlcv!_p= zI}e})AO>enFK3MYT&fcQ0F-Bv_ViMesa2$BP!=elG>#XpR+)Y+fFQ`$u3x)`J-W5* znl)&p!L9}R)-Bwra_1hc8{{q8yL$JoDLY`mU$t|+6eesqrs2Rx3mXWcrm|(rh}U|l zJUL4inV%u+6d=Gr7}973WDe_vwCOaer^XiDx^$Q{Y0&1D$vY-)({tva4Nknc@#DdP z3!fUGw{w;O0+^1Dwz+7p(M_X4gO>YsFWXJak%N}}_wnM%$5j8EH~KK+A`mZ literal 0 HcmV?d00001 diff --git a/source/web/images/icons/layout_narrow_right_2column.gif b/source/web/images/icons/layout_narrow_right_2column.gif new file mode 100644 index 0000000000000000000000000000000000000000..b129f738bc3d2262a6cdf0ce51ec6f66091546b0 GIT binary patch literal 841 zcmV-P1GfA}Nk%w1VITk?0OkMy)YRbg^!)7X^yK91zr)bj+~-GDcFfe|PGyOMtKpBa z-B@ghXnBvArM8x%v~r!$aGK0@pVLKKcST%xMO$`ft9Dc)uy}DrMlCoyw#_>)TX-ArMc3o zzSgR|)40pyk)N@TovxLmw3wx}m!!0rrnb4p*0{saw!zN1!_U3P)4aygyT#Ga)Y)i~ z!gr(AUvr9ahoEJ6j%$9CYkiV!f0L%X)ug%6qqxwgyws+<)0n2Vm!-9tr?;G`xV*~Q zw!+W4#nHLM(7ngf$k5rw&)CP$*UHk`$uq|4IR%GBC` zlby`m3J@bzE#?FiT7gH8KrNG%_3QNiEvj+rtV8 z85=$j92yuS9T5*d7Z(;5?(gpv^!27+Rb5wDR9047J+wT@5e3H$9Xz1$kfI~X4jnqC zOo@00kHw1^Giuy;@eTq4AVZ2ANwOqJ1YW>^@xrpD%a<-!zEp|wzyU9Ua_Zcf)5}er zJ`bP-001Y?qdm_U734(>0F-BxBAwcFX&f(6Q5Gm*bt+JH=9uY2|K9WdZ8Rl7Y2k0opvsh7ep2^$EaMor_RUMg$e zJXwH%%XqWE%#y`G7|)=0dif00vuV_KRkQ9XAdTrXX<+JxnHwl>({q9gA5OgZ9KFF! z2MDmcIZNh1lZRQJ8YuLh%T1#}Q@tm5pxaH$k<*<~izrKC> T2H?2a&%eL_{{Zd>M<4(@N#(nb literal 0 HcmV?d00001 diff --git a/source/web/images/icons/layout_single_column.gif b/source/web/images/icons/layout_single_column.gif new file mode 100644 index 0000000000000000000000000000000000000000..b02e7269e201e5481e61bbe684482a7a329290ad GIT binary patch literal 807 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 literal 0 HcmV?d00001 diff --git a/source/web/images/logo/jooreports.png b/source/web/images/logo/jooreports.png new file mode 100644 index 0000000000000000000000000000000000000000..1335ee7bc3d42a51094bb22273a595adc522d8bb GIT binary patch literal 6375 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 literal 0 HcmV?d00001 diff --git a/source/web/jsp/admin/admin-console.jsp b/source/web/jsp/admin/admin-console.jsp index 963009709d..1afb36f029 100644 --- a/source/web/jsp/admin/admin-console.jsp +++ b/source/web/jsp/admin/admin-console.jsp @@ -98,13 +98,13 @@ <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "ballongrey", "#EEEEEE"); %> - + - + - + - + - +
@@ -121,10 +121,10 @@
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "ballongrey"); %> @@ -136,7 +136,7 @@
- +
diff --git a/source/web/jsp/browse/browse.jsp b/source/web/jsp/browse/browse.jsp index dd66b092c5..2bc57ab8d3 100644 --- a/source/web/jsp/browse/browse.jsp +++ b/source/web/jsp/browse/browse.jsp @@ -137,11 +137,6 @@ <%-- More actions menu --%> - - <%-- admin user only actions --%> - - - @@ -268,9 +263,11 @@ - - - + + + + + <%-- Description column for all view modes --%> diff --git a/source/web/jsp/categories/categories.jsp b/source/web/jsp/categories/categories.jsp index 952eb2df95..c6d550745b 100644 --- a/source/web/jsp/categories/categories.jsp +++ b/source/web/jsp/categories/categories.jsp @@ -189,7 +189,7 @@
- +
diff --git a/source/web/jsp/dashboard.jsp b/source/web/jsp/dashboard.jsp deleted file mode 100644 index 190c6fcef7..0000000000 --- a/source/web/jsp/dashboard.jsp +++ /dev/null @@ -1,169 +0,0 @@ -<%-- - Copyright (C) 2005 Alfresco, Inc. - - Licensed under the Mozilla Public License version 1.1 - with a permitted attribution clause. You may obtain a - copy of the License at - - http://www.alfresco.org/legal/license.txt - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - either express or implied. See the License for the specific - language governing permissions and limitations under the - License. ---%> -<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> -<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> -<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - -<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> -<%@ page isELIgnored="false" %> -<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> - - - - - - <%-- load a bundle of properties with I18N strings --%> - - - - - <%-- Main outer table --%> - - - <%-- Title bar --%> - - - - - <%-- Main area --%> - - <%-- Shelf --%> - - - <%-- Work Area --%> - - -
- <%@ include file="parts/titlebar.jsp" %> -
- <%@ include file="parts/shelf.jsp" %> - - - <%-- Breadcrumb --%> - <%@ include file="parts/breadcrumb.jsp" %> - - <%-- Status and Actions --%> - - - - - - - <%-- separator row with gradient shadow --%> - - - - - - - <%-- Main --%> - - - - - - - <%-- separator row with bottom panel graphics --%> - - - - - - -
- - <%-- Status and Actions inner contents table --%> - <%-- Generally this consists of an icon, textual summary and actions for the current object --%> - - - - - -
- -
-
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -
- - - - - - - - - - - -
- - - - - -
- - - - - -
- -
-
- -
- -
- -
\ No newline at end of file diff --git a/source/web/jsp/dialog/delete-file.jsp b/source/web/jsp/dashboards/container.jsp similarity index 60% rename from source/web/jsp/dialog/delete-file.jsp rename to source/web/jsp/dashboards/container.jsp index 228626540a..f5b8745a55 100644 --- a/source/web/jsp/dialog/delete-file.jsp +++ b/source/web/jsp/dashboards/container.jsp @@ -1,157 +1,126 @@ -<%-- - Copyright (C) 2005 Alfresco, Inc. - - Licensed under the Mozilla Public License version 1.1 - with a permitted attribution clause. You may obtain a - copy of the License at - - http://www.alfresco.org/legal/license.txt - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - either express or implied. See the License for the specific - language governing permissions and limitations under the - License. ---%> -<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> -<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> -<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - -<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> -<%@ page isELIgnored="false" %> -<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> - - - - - - <%-- load a bundle of properties with I18N strings --%> - - - <%-- set the form name here --%> - - - <%-- Main outer table --%> - - - <%-- Title bar --%> - - - - - <%-- Main area --%> - - <%-- Shelf --%> - - - <%-- Work Area --%> - - -
- <%@ include file="../parts/titlebar.jsp" %> -
- <%@ include file="../parts/shelf.jsp" %> - - - <%-- Breadcrumb --%> - <%@ include file="../parts/breadcrumb.jsp" %> - - <%-- Status and Actions --%> - - - - - - - <%-- separator row with gradient shadow --%> - - - - - - - <%-- Details --%> - - - - - - - <%-- separator row with bottom panel graphics --%> - - - - - - -
- - <%-- Status and Actions inner contents table --%> - <%-- Generally this consists of an icon, textual summary and actions for the current object --%> - - - - - -
- - -
''
-
-
- -
- - - - - - - -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %> - - - - - - -
- - - -
- <%-- Error Messages --%> - <%-- messages tag to show messages not handled by other specific message tags --%> - - -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %> -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> - - - - - - - - -
- -
- -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
-
-
- -
- -
- -
+<%-- + Copyright (C) 2005 Alfresco, Inc. + + Licensed under the Mozilla Public License version 1.1 + with a permitted attribution clause. You may obtain a + copy of the License at + + http://www.alfresco.org/legal/license.txt + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the + License. +--%> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + +<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> +<%@ page isELIgnored="false" %> +<%@ page import="org.alfresco.web.app.Application" %> +<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> + + + + + + <%-- load a bundle of properties with I18N strings --%> + + + + + <%-- Main outer table --%> + + + <%-- Title bar --%> + + + + + <%-- Main area --%> + + <%-- Shelf --%> + + + <%-- Work Area --%> + + +
+ <%@ include file="../parts/titlebar.jsp" %> +
+ <%@ include file="../parts/shelf.jsp" %> + + + <%-- Breadcrumb --%> + <%@ include file="../parts/breadcrumb.jsp" %> + + <%-- Status and Actions --%> + + + + + + + <%-- separator row with gradient shadow --%> + + + + + + + <%-- Details --%> + + + + + + + <%-- separator row with bottom panel graphics --%> + + + + + + +
+ + <%-- Status and Actions inner contents table --%> + <%-- Generally this consists of an icon, textual summary and actions for the current object --%> + + + + + + +
+ + +
+
+
+ +
+ +
+ + + + +
+ + + +
+
+
+ +
+ +
+ +
\ No newline at end of file diff --git a/source/web/jsp/dashboards/dashlets/calculator.jsp b/source/web/jsp/dashboards/dashlets/calculator.jsp new file mode 100644 index 0000000000..9a2b566850 --- /dev/null +++ b/source/web/jsp/dashboards/dashlets/calculator.jsp @@ -0,0 +1,22 @@ +<%-- + Copyright (C) 2006 Alfresco, Inc. + + Licensed under the Mozilla Public License version 1.1 + with a permitted attribution clause. You may obtain a + copy of the License at + + http://www.alfresco.org/legal/license.txt + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the + License. +--%> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + + diff --git a/source/web/jsp/dashboards/dashlets/calculator.png b/source/web/jsp/dashboards/dashlets/calculator.png new file mode 100644 index 0000000000000000000000000000000000000000..4cc80aeba9475d74c76297469fb5442b90fe8f67 GIT binary patch literal 1920 zcmYjS2{hYT7Y~Y&mZDl38lh-vZ>FhzkVtJ4bkUR(Rc$e9jlHVL*vX8gZAuYqr;Mqk zw#u{!8l0gObV?g-A{6ye5kZKA@89pV=X~#+-@Whr-g)o--hJ=fo8#r-tO$mHK_HN# ztBcclz|#OE{~!%mZ}=Ak;EZE2mt)bo0bv(X_i#3`6tTo?>tZhi)K z>XfxP!WwA>GcgB7`nHM@A!0Df7G2qRr9>U{&Y=8 zZQmHFw{=y{v)tBYapzzn-;_;puzT03ZU(hId>{jrq+(Lo5k4;JevI@$#1$`(-7kC1|An`e-ZhqZ!QT*0 zVaG%*Ttc#-TZ(^Nw5s0^SIqyU`AefX#iXPrVs^vv9JkU}2> zLP+U(!GGN+$efxG^?N9hV)mrOM@3Un2CdZ(5_n7$E5Y)%sl^%g^U(++afrmXGYcAS zG?%jU@`)LCZ-3rA6Jw;QE)T32h?6L1jh4^|<%Z<7b&hlX!nK`8LN+B%k@RwpDSp4a z*qYCww`tI2=e00r&S}-}k}dyZWL6OxHf6zhVQW{?8_7}*=CjiVUB$=L$SgumS{>)S z|HM>{;w=;KiXHVOhg~o!nvobhv?Kcthj(xDEjH$Yah!0TfR*v~1<6jWK`e;G)&>io zWQ`69gppkm5q7DPM2y4WS8VA8!-~T?%e!Z&sJjhelvc86{tUUMrd!vnYmEA{m88!{ z8}-q&-_sG#x25~07Dl&iwKKZ7K}kj4*@s^npy{nP0Xv#O&3;1D6e15ri2p04htp7T z=-0-9N-8M7?30cxJIn^Qyt9M@#ps8G;DP=%04Ep9#@nZRO^wyH* zCtIjpaqU{^swqX}s=+^+a^$^JxJl7U1$2ZF0-ucRyUiU3o;}q5Lu21c;$K*CM6mmv z0Y#E8U11*F!K6zbSZrF1K2zOoBbvOzdoG5exE(uFFp!)JtWoMK>=hWuX=l6)k%2_; z%`81qXlL*4rW3#nB$;1JzL2=xzNG(2Fk(CdK^D%r>kzWu5tN4@X$6+D8I9r^ZJpm} znT&4n3GXSv99V$)?c0h$eUEZg}+Ri@VoPTX)dV2k6W0iFV}vrip}w_L04Y zL8s$Y(CZHmF1I0ygD`8(ZuL5iy_Br_@R}aM@W2K3ef$h0?nS#l)5?QO!SxcrCyt74 zLnh%C9^7@3b#ic$<@Fuxx@qINB&sw)ajSK;)Zu@*nqCl1eaqngXL0v&PN=cZhpJe5 z28EETpJzi^;Z=IIkdOCp{^mH<(=r7C2`*YX@ziU@GZ0%+>B=mGk@4fQC2HBSf1H7Q zM>P4!i4sUkncW9Fl5vJ}^FsYYq&grl_Vh%U`syOYHhOD4&k#0==08~&7dolV!pbgu zDtT{6gr}D+RVgpx-J%!I-N3`H)S~!VRJs;R`>l2zcz7o^clC*F{0E)w)B1A%WR@4S z53<_Aal6&C5WYC%C%@x*c@B#n(z8n0p=|*J$U@7N(HOb{4|UQm4@AnK$%(ndL)oD{ z`M?ZM(qte(z_0lV^12z6fgBQ?kRs&viR&EjkMu|=&X?6)G9rr=ipOlb@f>irQt| z`d2P+CPAsJj#WWUorT;J#j462`DaRd>y&XF{CH!4kDlg9oQm0g)o;WYH^d!U3#aJk zgeH2QS9(*~^8CKxz-Sr`twQv#es!*T;Mfu6$;(OhG7KbGP%Hgiv^mKTkjt#t_x(no voORE9N0o0i_j`#2%N96PfmDIEF=OAUyHV48-}eE~@<6T_52r@d)ztq2)#9jK literal 0 HcmV?d00001 diff --git a/source/web/jsp/dashboards/dashlets/calendar.jsp b/source/web/jsp/dashboards/dashlets/calendar.jsp new file mode 100644 index 0000000000..90ebf9ae5a --- /dev/null +++ b/source/web/jsp/dashboards/dashlets/calendar.jsp @@ -0,0 +1,22 @@ +<%-- + Copyright (C) 2006 Alfresco, Inc. + + Licensed under the Mozilla Public License version 1.1 + with a permitted attribution clause. You may obtain a + copy of the License at + + http://www.alfresco.org/legal/license.txt + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the + License. +--%> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + + diff --git a/source/web/jsp/dashboards/dashlets/calendar.png b/source/web/jsp/dashboards/dashlets/calendar.png new file mode 100644 index 0000000000000000000000000000000000000000..7ce352135edd92e114b590247b15d5b0d4e61eb4 GIT binary patch literal 7239 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 +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + + diff --git a/source/web/jsp/dashboards/dashlets/content-checkedout.png b/source/web/jsp/dashboards/dashlets/content-checkedout.png new file mode 100644 index 0000000000000000000000000000000000000000..8063f8b4a5c4784710261f95d74d1989bd3e8ca1 GIT binary patch literal 28296 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
;Uwsh3l9U_tGj#`tOb?_I-{&u+5qIv4> zsys+uPE_o8ISOOdv8?!zs7)y>3a!D3nIJ$3^mD*n1^ji{2z?$w0rC4o6vP!0^sGx|ocYCk>u55g`(rSm zGhx4l=_rCIf>q;^rlQW*?;+b)MJuUp)@#=}=Bk7vYB{3x>B`FCN z6SHjAG^btu@%j1Tq381D<%Rv{3YE?hg*RXXq;F>6#JxCa5_*~YxQIgHQF_|g0Yk!k zkOCrHO0gO%LQ1)&u@`Y%QVX@J1_8UU1gF3cpt^}#>J6f|gTCjXca*pvQW>AN7inpc z;xwYFvnh&+%qD1re2ivt-8h-uww&NEpCeafy9nhf%Fl<%oV2vsfG7cFk%s)FJADLS zJDLxvX249n-rf~3e4wJdeEc%y6bCFjB!5I2;I4Y;_C;wqz>EU_obA& zNUhUO2ZsTu6Ac=nx3t4F?d!4y2${}7{gm~6ex-p%?DhG$9M~zsQ)X58p*b3(;_!0? zG+@G@LA>^QcEU$wSo^uhXkopu12}CXBqZFao;AhB#GH#ohZ%TtJ!$*7IC0ngOl!40 z)D*5C@XrzQ8&9uWK9(nd{}B~J4DFQtK!i#6&M+ za)pAb{0i}o{eXn8*}p5+y?oJ5Ss+oNP|}yR(d9OO-AT!-db`*xpZlz~;;5N|;v0R_ zZ0nn17COjy&-=K7BVL-B<1m>=kDrN&{%eP>>QrFVV&lLuqvJ$< ze_ro&z2Eo|2z!KWiOtRdzq~$g+!ynHhCQ@JN1vy!t;NR1y4BBVP5^g*hJb|LHdmd0%~f#BnSPppvR zY0M`a%t~itl{u%0XZ0E?MWC{)S-%~tDJY8N$Le=*UkDzSWAjSC1*i2NcJWll*odtI#VncfEIIk2Xie76fg@C~wb=lDQ9f_aXPOEU@dmMET2jVx&I z!{C9uQevbE>_WxvPePm8YP!5g`at#oM|gU<9;ZAUFxGm!UWNy&P57X(F!c*8g(ZN- zdU&}TbNZO$5QgYt&}=?T0frh<%=H1W=s)gD=szDAhDu%!%CI7c>2ERdkx`bdv7Mdi zECR0-e?2e3-=<8yJPB1l)(7`m7BUfbIO$R6&`>s336zDpno3%6;m(+_CW*b9>7v22 zZazedlcq%L=N?f^z*|)ub{-Tem*21V)=fFy%HY22;~aMn|*P_(^q+^emt z19p97qiO3l3Ce67xD|1u;g0ix0uF**bO@nMQm;=s8GNc>Tmg!Dt62Y9Mg#0yIK4Ol znT=3~GqnEW!0adz+MWgAEo&A4xm>P+a1s&DBn@0N{fUtgS2G8d*d)<(Gnt<_ipxDt z2HR8J*jNhgZvZ%Hxf?HIv3%6nyMbJl15);+nP>p}emE;iUBDVuzFup5I}u7<BR}-v^m*y6}qo@aN^&qU8Do@Ob=WFh(l#~a_5@Rxz}wOu@c!P z^uuDxW6&Qb67|n3$f=ZBP7mZO_qA5bKLbt`$fwO>KDunfhbQ4Ep9Z?9vw`%0L}Y|E zZ$WEZ_M`ULJde427jtAKa2sNwM^|apww-P$@&d$(A!4`02ZfcNS+xb;M{~M!AJ%hv zY*9Cf_sQAu=IgyDX~IV3)5&d80d@Kb5eg)?TdsUD%PKN5vVjyobAD$>*TLaF2nua& zeO-xC$;Zb>QgWiQc`GeFJv}xSz;rr6PR4!nMo>g#-{3imta_2PuHn;Z{5&q88z##H zPi13ei2%MgV15zhEj}CI@5oL1wk|t+SCM>qP<0pO%lr0Y_j~4RG-t<9NM>dAK27k% z$lxtK!K*PpleNa(6(Wr*+Ag^AP)+Rm)+UDyt843S4~*I@Ym?KD;}#af`gx!2zqVF` z!&!sDBuS-`rd(MUON1e;E7^Oyf3xhmtaVo1MYu(Kts!u~Z6l`|ntYZxURzW~rg;iUJ@_3M@xKBCzeSs< zMRm4+n1~+?_MpnZz+g}b^51VfdS0`f!%sv1ppOrKh-OCP^>&y1e^#Imn*ZbVzkJ?M z|0+g;_+Knw%P&zE@f5ewO6=>Jq^K;8UQCwXUJVdA*Mfx+q3+{F?x()TN?>@_XmYPn z31r?OtwsaxlfKNkReAPQ)aXz7~D*+JvMSjYnPNf&}UY~Q`RYr)<3hEmaYUe>p; zl_BDhPrJ3FZpMyed1J*V3lp=ase1D}^kz25UW0^$q-W8N9gbT< zVspZg!l9_l@B();U*<%N<_vPUi{UKRgq*yhg6JErx}^l*y)jurkaD9?1dm(Y9 z$#%&KwCnw-UjV~MJRZ_IdiZ5w=`ZF zR=Fz2mDQGckOkci@@%1;ht0Jhdi*x#QX#=eeyrE7C(1_qHe-qoP3Eo5E}d>wL9wO68y*Z6e|yk;AvM{RzMHb0 zQ`vJ1bFS!@Z@%M{KJF!I9$aJNP4S?*lv4_I82rLowuN~f$A=FTd{L-blvW`%!4YJv zg$JOOo`RkQ}Bd%<=yTsg8u>Om19euU!<>~V_1pmZQeZbB|*K{($ ze_CfB(#Zc568e3h{@aoi@&CWzqgMGpDG~|mZND2E7G)3Fk733+lxgE)#`V9D+3RQU zY4=3ih12CE0@-Y8ajI2R>5ypgw0tSXd&`oPp`-Jj>m^$)x}>2SNB zDgXG_zz01~Uc3jGA}X5BZXZ7^OeC*suRI|r5fO}(YTW*>CZAi-3 z*+E>PZoTU{MRd#;3lOh64GSnJ!n{BN0)nd$cMru+%E`i`@e!w=b00t#;DD?YF1Jo} z$ZPQj@0|(5>>mW3-8&?ho0yda0J}8z@+#+09-vc?{Y@dsN3qCl_}0=&moV*RX(#UP zDC%1^PS#zxeE#&k9Y0zMaTNmFsq;RJwiQ1$VcF&i(fThN2HnAMnR&bUG?`irWxl-U zOh&&`{WG;btomaXPmS$02IN_cmmpgs7J*FRl&br*$8J2pAwDiY6ma^k;pBc(;G1oG z@Nj1xmDFS)2z0N_zb5OZ>Cl0UY+x!Q)#*}QWoPc+)oB-RCh7z%v2&T$31};b0!qNm zt`B*USQ4R7zHPwsYkXOdOAlNJTq_<#7Abnbhd-;wvNwSPWut|J!o=*(-&QXr1{PEp z>83@)SQ_@w;p;}|TtlaMAHB)TPTde3kE33c;5o>LYKwQ>jKLs=P9htb7TNZ*V;QAn z+dqJw?I5oyB0RjTtW3B;`CoH-!I|G$onIvb-}WxeMk_xVg%%dP&9WTR%&npaNbb&I zuBTI}GZB(uH=}0#Q+IhcfHvoI>_n@qEwD}!hGZln(!zJq1%#jQf(2YleA@{e1P5DF;HOfNEqd0V9S)qDsW5=PQ@{fk2_% zwH&lS_W#Ltx0NkyN{OV8y}s6k0(QaqIGrzkboYV>M!-uT2yy+`w;Bf`Q zc*G_+98TN~y@ga;#6CKM?MpR7;+>MdNyj)5pCA<&E}ZuSG!b`ClP!rv7(sfAp$_Y6 zGaWLdjX6f-Wg+I^CIyKu+1Y+bc{r_&dnie;)e9WUfkg`BO6WYaHrp+jQN>-RAQ)a} zQk@y52!Zzb7H>M9Vcq-;;7k_FQcq=P7B5)B_+FiPs}I=Lw7m9k)jO-VC`gSbvPI;L zgelr)OqJC65ruE&;H5?|RuF$O4Q~5|_VkReX~SD%lob<|5*Bt3a~4V$|BjyC>dix! zL_AN2Bal>MS5uXe3wTXR0dkEJ{NxKr9>uE!m>@=vQ$Y={2?OH`^h)i_`|2wSx-JBtkGS~)*cN$y)G;7kfW>zqr8Ay0+^H6 zwuM{WmS-rC1?MJBeK&Sq7xBCZMh*5Oqhp1FH9@y^HQf{b#pe+2Idn{AuIyZHW0#ZY zQ*dDKvwbE;^~IVb%^b~P#oE1&l`CdV?|a$BU_c~Lc?hexGF-=~AC!bRUcn^{&O9?p z{J3-g8}D*A*lxaVjbKixIU9O{jk+pjULBM$kqm<@?6XMcOs{&j(a35gQc1%_gH_Gq zy8mnU+6A3N#k1x+_I(PG#+k=Sd(y;bWCUTFKyh&kS*YJ+NdZ$Xjsfaq=txM2Qk;c5 z&+P0~IxZStOMVivnIP9P(i~3aZ^phjKa@0MndTw9LCq%3B4!swGvgKqltmO?hI3;o zRXfnn9)ce8pp)#FhJtFFce&5853I;x(DN5+)4t^L9CcOCD!b-%q7V77)c^M^@iT!8$=fN zS=1w`$OJ$OnC{rq;*s9?E=NpQM-qEPe{`jxA{Dv^fi1b>erZ(ZQ@k$yLi|3u$q<&) zH`9}f_eb1TjL(!iur&-^UuzSWY;cCa&X!y4`wL04p0-y6V;#U@;duNfpPN)#a{iE0 zQ^Gsn%5#M4a4*9x-d_kK#FL+EwK+86X^s>aqWpPH$={f0*eSl(xeg(ImE|BYN41X5 zfS1cWy_roD*nj>Co(Rp3(F)lr-#wl?HrnHLXvZLoqR9GGFbVj#}r*A!#vRj~is)9l)8& z+Zlls@Aa&$(7-N^E43qHfIQmjov7cNO28ExP88DFWvJk+^Wz0c5mS;g#z( zy**8P(w|-WvJ}luoqI|eP;fne<+4@+$bt5FlyNPF0#o+R-tIcM<}wolxMbsWDt*C_ z>xTL&IR_6q=}Y321h=Nf_#rT|<(-NnOkIW2;n3|11_OD1$)<5?41n));iM*C2Wo|; zGjbL>z8d21h7S(ZP>Ps5RI=4w-D#HdZa)@TQA1BeKa!Yv={1&;0OBGtL{=YdVLMZ)Jib3(&eO@D*Ok z=oXdnLSTy6gn@E3DBDIjYmNypAEqgCNn`>=?1@?q998^9Io%osCjjO1dkN~Ea3EVe zWOI0GOm8{Ca0dbT>N#d_^3VB6&`%Utw&$pflF?-KqBUr|Rh5AG%CWKXSY`2%8>atd zQmdJ+&N9C+JF;t?QIUd`N4W-_o7CgC{P*=fMp|NlnTCF*ymh?UjH&YJgx8v1 zK}iYC9J7n04#i#sdP1!#?c=F?aAYnJZ4JC?J=vEC7e46hX_W7HYC5)vH1S)%>x~8v zqh$60(!fl9OPlx_c+(Y`paNRLV-h$#{k<#8s z&>835^1zj@FW6Mn^uOdZJGTN{1#zY7@kB_)!$nhK6K!Qz9V^AMXYcvI3=9Od1RJs^ zi#h#aFkwiygug+xvXu*&&1`)q#YHuU)EY=Er0frnT~Y_`;3w`z3%7ijA8%SUd9Y>G z=<8Q4{e4K|Q$Lu|Bijfv*%;1(+O0FOG0w6_kq*C5vAKNra2|}#A0Huo4qB+iecyBP zTF_&k>i|}l1NJ`lFwdpv_gLhjyk2qG*ZZ1=VpRtTXgM^&?z}X3WGWzQC5n`p+#}_6 z+UWYz83!Wqb2ht)tnHO%Y^>xcY$g)pz@1g4S?mREhB2kt*w?MLa~e4Z!0j6=4Mbx{ zvO8)DTdQ{?J5CWn`;JIWw))U+xF`C1^_KDu*x?Q=yL_ICvL`xCgx2_xsw}WN){4w5 z@GeZ}9h=NJs$d(MVH#Xuw6OZ#f`IDTXpPS&K17bcb%iU?=_@OJ2|W2N7b4kaU$b({ zjb~*|Jy~hZ=lzqs_k(CBTgy9>X&X{)J;%B1>>XcPT)iy>{b>DKs4R8fh$-S32I?vU z^nJV|M(t*YX%-4gohS(GIyALcQ)I-5t}H#UB-HlbYi=m3GgO8Ch;7X#Xr1u5+D~Cy zju^-dSu?kq2UHQ*aZWCZ5Hvd>?K#)|g)kF!9dOdRmL3UkU$|x zof=B&{bl>o(2Bd9PSl2;d)M6# z2fJCbTAwDErVr%GQHSUbEJwC>d1Kh~WRY0BCx%s*)fkHd!CZVlrH4PJz!`FVA2mDm z0%h!j=b;!tJ>O1?`{4EL#n+N`JdNhyXgjTLD=sX%@COPdT-179#7a{z8QA+?XRFG8 zWp2A@C6up+L~=w*P6N7v%f#Yl{${mPR^IqcnWj~zMaoTwZrW=XB>v3bS#eb+JaT;6 zC?KBr@3`@~RMwMuEN#e@mjU1# zPqV#Z%d#$2MW}kK>aA0h_6KZzg$?RTH#d!7>q+y$mvwl}}^8hiK zbOt(mJ;Fa|0V5!st&Bjm+GwEo@wI_JD8qFD7ky!k<=j7z%1vNSqh3=Ln&^`2ygm(E zUVd-ol~h+hQ%2v}8ffYN?Cyuoy|MxJKy5rRw^Aw|2`NRWlhn(?c#jjksReR3YWR;b zHzr(d@ggl)(TQHbBYE|fdWrr4<%fXhW#CbmC7jvrpN{U}{~=xfU&C+vR|RZ<-BQbd zcN+f=01j&m<=rY%ezFW09iJRm?nvXM4qspt^&b)s2!faZ1*cavXs)YmD9PvXeomH9 z{PK#!t?&5sTDH*9IbTlqy-bg{-OrEUrprDvJzoycZK;BI(AN6bGS|Qd2=yrCP0C|I zI}il_TqNe;2$;OVae;!={9FLowZ*qLWv7Zzod$d}`4nIIGLMl5I|m)|?Dv(ugol$@ z02QFT+kb?QG>|g=HGK26{id^eTuhzeCOZ5iuK6EbCS#(=ze<69 zoTJxx)4I8-KWqfn_+(tWKRTvMmj3dKYV*Xjv0C#y{(e6uvlLOOnkcWVgi;Rs*Ij+Q zIaD)nlpfVuXTTj$3aG(%dw~>XVkv~;g^ppbAIa5Wu6^)bu`kr9Im)F--wcQMLGRApPxkmiroFk`b_R8NrVkO%B?M^9kb|?P zCO>JjkA{YlQuJsBL&I-9w!jd`7A!`xAgGq*EoFC?f6Ed7wW&sc4Y6LX`t%YS1^svm zbrQ41HurLU|81o=;q`Cx)*d1!1DChgQ268g{Z7+R&U`wI@Py@nWHCn<9zFC={)|;t zt+CZmxGmtk?)W@1p52IP?L!H(c_XH3jV(cpM07bl_CqNcn38$KDEP0}FW4r&o#*C2 z0{{5oZYjxdpZc>*lPotU-MP}<8VKag8_1WS^~l7CW#dwb#fU?o370^h z(f=6{Sk<^nLY0P$I<(6~wC~^!0P)JOAGvw1HuQk?n&0GYaY#KVO-xnD7c|ej&4#Ju z<$ReOeCi58E8=MvPGe`+pXkDB-K|3LaqWDloqNA}+ogo=56;Xw+0OLq>})xq=lQ69 zqYt-_Q55zZ$;VFMz#*BRYqwu%23x3qHv#%p5P$nXFtHo268&TQCqyY!hl4{t-3RYR zLi7nGN`1I?vb3`^m@;Qh>Og=LwG^P|STU7Vm%1~T#urbZlC_Bp*-9ELq|u-@YOfb6 zIm1!3H;$bLbZQB729Q?9lKJ}3ih;)r5?JeJURqbR+V9m>0yx-16W>=0x!UW{k)MDBEL8Te@^ZC()7*l<+`DrQ= z=9No;7uG$Hl>S4_7i@&v-Me3nkQVfhLH27dvBSfxeqmDtcnj>%aVjjJ!(MO?6a>>5dOn`xWYwV6UZL}~wiQ-_vV0+Wj3;kvQxSsxC+L95^F~VzPuk~4f;12^ zlZR|R*l~S8w)v|COc)QwL?1YeXAi~-=)7D+!h{FmJbxE6EjbOEQv5D4sLfMA%0KJG zzn)qHjC49{uh*Y91~Da7oeVregr67EF7^tUiUfn?cN-@&rIz2DX{I;+Qc1-?f%$bd z^Q4^bRO@tqEvo2%{DGGk&xI-Z=$OcFC2HIEw}w(wPV)VE)&aL#meP1UUcS04Vb?w> zQd-b4^{j%@36Ft2reK4HFgSPyZvGvIEu6@!HeI=@Rh5ar-wbkT9yE2vJ1txI$81Ue zI=`z*QV>HNEhtdUvBFSvc69U|NX3dPLdw2(a{1pN&n=VxH+d2+&Bm{qkO=d}a^9!H z+>_k?#ovjk1b%&`>D0!1c+08rj@jb4T5;#w8;(q!Cl{xtsW6k5txGqrV+zNPj3`MuwJf7$e1@sOUe}r-ttFZVoztHR&BJ0ZFn;r zu8HfY7fF9dHZcTKwhDy+UUx#Y!&_p2f(a*iXMF0JDvp#)^>8utWIS&H1>00VbkRcl+WdNK-8!nu?IJ*`EwJrj3ss{w z`+Iu&cV7Mdee30F=31t+{`&kopnKX!&8g%xaLIHkJo%t_yUltH(xucBR|Oj{)$(4( zInJPOevdFi32*l}S_FMXG$VxkhcE+WD2pzWdrb9h^0@fes(xtOp21OJF0+RP$nPD@ zyzV(1V-Y{Y2)EvvS@6iMhwMMlYyb*W7fS{Dla+F#XB6l4D8y+5mQ(y7$2$N6+96#= zQOZgEgdS!JpEF8BP?9iTjRq%sjH3VHt4C_I4$>*kV|EMOm9shLBE$_4+1Gk&b`Q)? zupXH)>hI177m6Bq=_2eK0WS29qdU=#{SoQ#U!<@v zdfbns80cZLS73%c@~Wyh7XQk3h*rh&3bNy4SSGU3DR`###W)VnV#~~e-~Gk!J6(}Z zqRr~cjZD++lLg9-$WqL{j-4#*i-kErmWg2X5AaA}dmN><n1m%+O< z=?I77ezH*uL76c5)`O}M_21t(4b?4$^BR1I;cjEai_E2>B{Oi-Imj5!%i8Ysv-wM} zV-N=h0tbR^1#(paV98jBr3WHr&>g+h6PF5l0a>UBtfCBOlPZ`;|0--4A&v{skCP?4 ze=jcdAKSlTpOpT8A?Lnc)(qNC4IuJ$PPJxrwF=nQAeBrH&%(-nkJ{yXt@ro~+n7c?>z;4w=-tHTZFIv!xq#;PZd+4txm8-zQ*Shj zlu3Hg{u!UgI-ke#Od~;s4mo|qzJAlxgpcDFobf<7;QSgSdLP+<@MI`b<~2r}IVw!h zkjs7^3ytY1tMsG+sk`L5XSgI?wrt;Q(8d@kJ?&-phojyDWH*ld7d)JfRO8_U(!B0WNN`%KjMWWpK z1-+v>HBl9)|p;cSf?f`!zV7B*LDZOAyM%>dOnojD^J->|x7ZqnZ z9k|`;oR;#9mON#Vuw=BYcfy9BqoYekLwH?Hfjm=Zpi=IvD!{my5k&I(UD<$u z=+8yQPwT0@u!hgPLET-gj4*reEw#;8(lA=29EKi-qKCi-Jlnr(vpduu|OB_*ObTRuOw%1D=XQU7AlJAw!ReJ%K2iD?#P_IDodnYSp^m7WS25`(}O zMmNWGH(aWWhYOfpcEBHkZB*Y}UB$q}Y`b_ex<8(TKyq_YcRso9L$^kRDkkCdy<&Vqk@DZ9X0lUKqRr#263^WpOzX#6L1l$e0j}k7&3oUhcF=%-< zx8Gj&V}9}-q%+ud)s}voO%|)Q-(A=LS*?U4HLY+bY7;4iwF-&oC~1N`kr%l0G4C2Y zuQcH%*uR?5qW6mEexzT2{b$h%!<4r}9$g&L5B&$Ne33M) zyBx0nSOgg3__(Jk{W+|CYWCCfN9Jf8od*F3?dk7uVWsq$bzSWd4$3c^-$ud8VF@^m)uHyH0r?+G&GPdDMO_*U`p zmRxi?mm=NJN~)ocMIaTGkm`k#C(g-){dlxAoF?19LS%t(UB)Lyb3Lc?&ZfpkMO*m2#yJaw7uT@G9^yzI0;hdm(?ZFhccF5j zBb4B8vt!BVHRubaL0GND#?;a}@HNqo9+l7HWQTi-L%x&q}VB4!pIqKl(G_{`YTKJqv47^wKnpy@O z>lbfnL(`achm(gG)Jd3cJ=BxW|GTaCd!GWeh*tkg!phAXW84<3*zcF=)Eq5NY3wwA z+@`tl1;?!!nzTD)((M!%6GwrG7x-Z6>aT;9g3)h(KA4Kqv%O$irpC*SU~K`%(YB=5 zJ1R2jShD>L+M{RSvbu+9F>g`^g--XSp3Acfq6k>8>5zYUs&T-9U92;o-*!!&bSMV& z8=`aGt7PKJS>U&GA17Mm$rJf{Z$v=&R*tCEQkl**_c2ya@6il;oVVToRDljH0nF~7 zonrF`z4*(~b;$G<9St7x!b<`>5aGC=%L{5Azh`%TP5cU8YbA2atXxS3xQbia61pF( zBAhy;r~#pB@gJoYLtPG+P+-UcNq-Uf0kv5 z$K}YynLQn!aC3fN_vPrL6(;C{1bQ=y`%?D; zfrBn1Rq`G>$JF`r-E{_!Kbw^AC~i$oN%+Ga?d7A;qUQ`ZY;sx#6yAM@141t%xfuEO zSjlG0KZzRR`LNqI2VzrWn9QqH=hvELX9*pqqo>urFcH6FxX;KTgN25BCBPvk!M||N z-hcBa46TIktJPT#e#3P2aEyWL{Rozist}saERTemB$4PrIAd z0(s?{A|ZvW=g1rSj-AZ0_vG2P1emvZ+q3#s%r0jUmRrOv2hJx9XyY~q2oD9e5+uxA z5W0nU$OXCAm_K~T8vVQ!K@HyEMP6Zlp`q6E%6x~lW;Z^-(2BTQ<{jXwI#Ns$Vx*uz zHCYcw$;rXNw>A1jd}bevj9eeIamsQ!8P2T+=?xwe;8sHsj-P=h#;0Y z151rbTwe+Hwezk^ct32%J7LFxPitsJWmKRM3<2Ec*-E1c?D?jsuD9avmh6~`!MhBb z>dM1x2KIPTO-UkfU$PAgo%vWwSC#C?`cj~gq(-86y8ZiS(wM+}ljNdLwOET3v|GXr z1@(!zgH}vczB8E<@W}LLsk(xK> z?VrU{`tar8bZ$i4&TyQ%19B4Ww?4gAF#Z?xKs>ie*y9R>2#MOKD082#E`~_Z082E`LrtTln1z^4o}Z1~E>U zRFp=DEYA-a{WM=13VDwcLSQ>)yBXS63ww&@ciR5!W>ZelGHBHNS4kXn!F3umBtz)A z=leR=FOIr0$uX#CCJ>*Ss%zS0F_RhY&jufi>g~Sljy`?CN_{D zri<#qA$EtB9*cX7sDZqT(vBiD}7t~n%&dko3h+QB46PcDOP9>l&{3YOfNp2 zCbWM)0@eFE9wD1bjtHY}y7S+SbU*nqppE47Xir4bD|LQC16xhNz0AUJ8K|dfWROxzJ)r7)7adUG^d@*72sfX1i?Y+Bo9;{sq7cv8l!rvl{|0j0`w42-i z=q`IGL)1wcH=0ekne6hvB;FQ49>rMD>u#1V;LlahXS_Fq{FReaFSf8s@0lNbegp{K zB~03lm27)AKiYI?@_@flN?NjH>EewYl6u2}6IqJ}W+u1Y+6^+1aJLgXAxyFd%^p3k z8H_keAn$vv!Th4a0OeCqzA;8*>RNdfS*fY2@}WT>#r+dz>1FlZMwc8QibA8p-d2?q znC2G2#ew|(O?+iciE0PVuZ68{Gu@2uFbXzpGs*FL3{%5!k!%)eJMcgCrk~WDn`aTH z%-1F^fG-nGo94>xd8DFgh35kM;wSCIb<3aN`HRtwwPJQ2gG#VyIn2p+AE|GPvq{(g zBzQLuW^<|VkUZm-(7t$LB-gv}!1Tqo~I zVG6l;u9iPs%QLysM`TcjDOW1kO;kXuhMHg}8f#xblS4r7K&neXf>7=D32#$xk1M+7 z@og#9i{U;4)eKg;vBK)YJhhN&Bgf=A%j7zQXzmw0)%KdU?GDdGkNDWpV@c+IuIl8P%Vj@4}bOVlVM?8 zIy&@$@NjC#*|hxi@a0{D^OPk9WN>zD-wm7QhMDDFw~=9T)#69$SHi`(x|8CSQ2eAe zdS=QYKU+$VySPE^Fhz!dW{Xp+g%T-{6+NR42) zs$QRpO;+Z5uYER*ed+H!2qh*BS!7W*~B|I;0+ZxWxGV#JJF6q*&rKeDQXU$w%PIou+2b!J-~9Bpjch3y8xhaR(Gr z<38!!oT>Gk<0l<$w}*z);n#P0j|=ToP=>4_vCya6Cs*wKf&qUR%z%eMy7f}`9)775 zyDN4o*mn_hjSc>F0_^NapT>c9Wtmv%J=kmPH6aaPVE?6%n!#vMIGl0T z9AIi{YGSfCZ9Kxjz~Eyedu!4k;+uM%rSrVQo=w}WkMqrzUqb7$94%kN0T{;~Ld&

?sm@ zn{dp>r0ZvZa=cBX#?)V>R?KPgAIutn(lnGlR3WH9nOO`PmS8kmgcy^^Krpr+s>jEg zb5%rMQ$O>>^}!^H&j@D*#yqn<&J4p8r*j3tJZiFJy-ExAE-G}_S=kBaUnhsQH`<%d zaY3kn2Z<8N{;L&ETz#B!zH%d(P!@WqtanRZrBnVky40)s#s;Gf`?&fuoGn>G7Z@)` zYT~7(#^IoX^&}PwXP)Cd4Ls7&KyK92u@loUAujA5yLG!Zh{YRvAu z^1eSBdOyv4&y}P3c+vDA;OlSvhSx0;IY7_5;{vi<+4Murkqd$qC|=`&W8W969WpNc zyu>=Ut&`c=<0c+^(93N+*CGuU@A}MQ2t5u)i2_#9-^yLyEerd?x!b8c6&mF_Zymbn zppO4+Mq8KV+0>=#a!a@K!2W%GZ28H=p3F1H$%S3NrA^@inp-Podib%cN z8FK=Q29R<(JIlL_NJn7}g`^F4BVXkepYvU(%}VOnkrN01;q;a&5OY$_e^=_yox$K2 za-hzFdwI5?_f5+q&ocElUyi&!q;9EJ!Nwxh>0V#|c* zU~i7&bnv=-yike2$vstrzAz~W^If0U8-tc83SKp?CRPuC9a_Rrz5O{q4WKY!r;u!^ z5d`o4aP$TA=G-8aa67csz7^hfxWs8Mg4P>2Yy-^4R>LG$XJ!SHl5RYmI)&MGQ(&cG z;I_(-;+oi|t&jBX9}R8og#Wmq?I7c`&Hp90Z#s9rXwF=(t2=;;hP|TOcCru;N2!>a zj2Ld`nR5{sgp@}kZsr)X+iu^W?*mu8z5e2NqqOr0g$sJ}^miWi)5Mmz8Zk!|Ryqq^ z2A}ksS6WEi-<7{C`7Xf{7nNg>E2877&1|aciG*cOh{*ccw#=9XlY=IG50(v@!b~7r z;afEMO{ONY=Sm#rCoQ}QQZECSm#1*l4fCsN0h7?@X3YX#7 zayaTHSV0%s^G`ku)qG};hls6(%=B%w&I;ukyonM249Rjvyq3kLhNlxBjpvI~^$soK z2xRCJU2mL-eQ zL8m_#af*wzrf5+emN=e-j4BbZz~aoJeZEo8rS)Gf z!ZAXkzds47I9H#BFByD(?`U&~vfgUGemHpjjhFBuQjhmQ+S$+5O^nC~&rI(d;6J(M zm}=6{XQjWimbbqs=}=!tW!k{4f4NlS9Y@+iPtI=UEX!gHzP8oJ4PEzRnu!lv$~MB1 z?icmSpCFQB>Ijp(Hpbk<{1|G@E7&v0z8K&bocl;7hmQOE)QvWjWKOAM^{g~^mhBd2 z9`rG^~8`fDbZ&|DM;3&DO;A}ZS%uT#@smz&X&vBxj{d5i@$2P!G-o9kdJ-|brhp`YQ2 zj+t?tTriPWF2HEe05x&GjbvOguiD}ped-P8vz4DpC2ri#fPB!#n2BvXa=t(wj*}Yi zN!!!RnIt|Y@1x^^$bP3Ox;wAi`S`Bx4d_&L8Fks4+gR6*!4g#ghiqB!f#O$T>qrHf zl;xYgFmkPLK1;S54ks^XYNO3MQ3sAkO<(IOn|RO|#k@q0Qd2tfCE`DGxCtq4KnNYc zJYEil>=itTout26DvG)YGWd5D%xfP)fUhJt7KkEIha^Y|GvZ~?gthNlK8EZ?CSwV@ zK=2bB zDzxtpPZAS=yZIY>u#ra<%58Y_>9#c_T5riU(`|{gyXsk1AY#JZMk|1hhcR zQE-UC&cnd5AQD-w3?Vsgh=YF90UA9W6OlV}c!3z$WOC8XC_KlexmCmxbzaO25?n|BiHj z@xI>ETA^*E;dvB@O>1kevVsj3z-Qy@kX|^uebo3Ki1DI69wITE?d@$9^2jG7hl%|F zhLIiH4#-NX=`;N**O?PksI3mn)^+an5d#Ka6;vn~)qUk_H31utTL=$6J%7upG}Yiu zDQ^&bSO~3eCf5dNQMp1y?0Hs;x|dX$=|vnuE>L)_tE`ujJ#48%MvOiRn;3zgI=>@! z4t99)9s%6vgnzN>t|}3rjh;rMYc~8a-RnmN76SCqY_9f{IHUVD!+4e(P`czVwOzJM zmwzHp7kGqwW^qS1p4urNYGSNuVC74eam~r+r+pS(U*;$blbvor)FJ++DGNohHufit zvz$4wJAsW*KQNCAmZuGwLGtrhkF`upmfrU3`h=*ONG2@p>^wzDhJnN4j1ce5%IB|J zIWX!=%Q;8<&p>1j9i_(E+B>*1;3~L0MGbt6=#~5=g(l>&}wQC7aRHz_!$g){Ga&%@6UZpIri~V(Sbl{_RkHI3 z<6z$8iBunD292V_x1^JQRaPp)J{V#3xU`GW(o(vmO6?(KE%-`n(QeXi=ER;>6gDx;e@Q^s?EyL)lHgxMGX*o9!Hu94vdqj80)o4wmgQxS`-ImJp*dQ33#Zrj$>erb zDzCE%9=ljZWXcaBr(rG1vJ0r@O;nK*B`(EJP0Ww+&i&8UQFnJMZseZUUkAYX;SjdC z&@_oPtCXwkQgf`O`GrG@ex!6$&}%AEd0D|eOM80n|G`KcyK-GsNgdn1iyLxC!9H$p zwlfY4N~^GLyFY*bo&Z%iWV>BsO-OFD?u7*f@e5i}^t%uL$F->1niM30--$MCbo5IFPU0aCIW&445P zw<#kA?G`7i6fVBnS`90Xe13xHPg(J`$$O@o@4&`EGh?qFfJG=Uu%PJlpzXD+#9%UO*a^ zLU_39Oav$Z7Pv3L5-4oonL1a2IBj=Qj)F+)eS4pu(cvBT?8jrPSNI=*9Qs1uks)qaKL8o{6aqX}DNdG!)6mqc0Oc3|0+a{E_(CEL(I zQy&*JC6pC(0%Lq8*MIU6L=S|%iH?_=WLg}b>DkfT?Vi7!zwhtJj?+lZX|XuSHnmE1 zTRivBxqRX5j!Iw6j+;k?d4G<|eRt|vwYeoqR@XLL(oCe$J~}$eS=+gO{1{&dT!}z6 zn)q@0(Mli`7fod-2+tyjDzcX%ppxU%b-UYSA!8f^$bvf^N^{b4czObMYNLXsFc6mg z9WPFQ(l-zSY+nx0@{u_N3)H<}-Us=F^ngtctbp zY_6R_W;(4uJ>-_kHGjM~z9Hug6sYv;PjkJKYd&i9e-guCRivWWUAG$I_2=O1vr zUzRjI&=LpskfR*n(1l(GjO~6CSl=#prWQ(=H&C$b*ak4lw1sNYhCXZ${B+B`&8%2w zjO5hOseD*D{T|Pd6P?-iM(OsNe6@@`gahx2c5K}Gv<4np-Mw=YcCMR_ zk-6IN{&+X?4w?V)c0hv`pr@PNPs2d6oor@)nTyQ8yGHN08`8=@?n}*(7<|RoKCh&n zR2f$0bDSiI^!4uD4n{&hVp$$D83<;v$ycZbL)g4wCJZ-A@%`+#?NqpCE&9_1KCzGF zl#`)b?xsYk}|6h z+Y&zax6;tAMiY+V=1zL~bYa-{dph+p{}*9)*NMb)k9GmbbkDs?HevJ9TTN9fhS}!^ZbH_#3$FQ*Ze_ zXODY~bKVwQhT%4eB3xG`vu)p26s{}1+XwSK6Fp?g43aGZ`CA= z9dq-}Nz8;fxDF{K7=N4kQxX1C0=`wnQQEVjcbVuh>oBd#g@n~s(-UUl6CM4!d z(^NV%fTbZrC#M8vh-j)NXs>msdy-P&MFBUP+sr4E=+C{zsQ1n_J8%+bEPW_DBpF^L zJ&C5nuoHbF`%udt!qpJB-+Gg0*WqquhStYP15bm@^hX)CpSZNp$e(^xJZJ>(+XV>d zM&3GcHQtp%W|E*EBm6mC6YP;W$Ns`By+RpA3P$;AejdCzwd3rhgbQqf4~5)O#j`!E zG}s`(!;gD)^s^YQ#x=3uKk@;miAL-YYnX*jW?GdTlHdvDtt_nCZI)1^NpaV-)@kF9 zEvzrM$|m;N7|S5832;wiKC6UVtu4i1uO*MC6x2M0kN8r#rVL%1&LeC{NX`WhNCyUw ze5qDS@-V__^KKK$9iojP%y_0bzPO-Ms5RFW7seGJN9HH-HvqNiJnxaaScq`*RO1^Q zry;~N7JC}5P$s`GU)TwW30Do6D6sY|;BvVjfc=!;XuoAyqmFRBwewA<(Z`a| z%4$r^xq~95QodA18GG*cH8m5sIs<16eb_(#?xsof{sS zM}RkQKv1FC$`S%oSg{shnr2lf1O4nAMQ@|vE!7B7`!&+L_-RvJ2eOFgwb*c2M#F<> zf0*pDrWyzr*G1rdMo})w&MkNmlNy9t;%L>BcD%vT%apGJ1t+bjk0k49m)qiFN#h=x z3^Rd8f^T-q`D#mWyM_cC>(nc;=rcxsFgpIVJakS#NdPA9X)uH>h`{cl3asl=aMSH7 zI3j^b8aJl5*vrlKC}|uYT$3|}sj5nzY+HEHL-7ApWa&^k{|%8vlgXqg?CgEp%_)}F zoptFBC#3mRaN#~ZA{r~|T@P)>DAKHRd)5iebO?X16NU=GPoRCIR%*T!Nt`mq=dZ-KP7JmBVVirr|70lbcnFZK5H5|ZKj4^4m; zwk~Y4*pKQIy3!+AU1nVN9J2G1bT$;uw=1mP=zxtc)gHm&34{YE}ogUU;x0i}?l#blzQo9e>AA3RR~1eBYHpk#b>7)O29*khonG^g%GXg zfl&}8wKh@q0bh@d#rRPa&UuGVZMtNQXY>Fv-O2HfGm<)T=3e6%wydE&7bFJR@Te%w zbhabWQSMCiVXD}kSG?A0v6i5|J?R=%g5Y`REW0ONn>H^T#?8jJJI#}-hDM5PB}-2n}jYG_8YylU$!lQ7iSQO z07DEkkV-xf;`gW5qJ>jsbn$f$J4IhLx&}cV7O(E!iwO2r+em&jobuECN*zA2LIPKA zr~6~*cde47@DzLI*TB8;rAF$I6w^^~jaZXOU4>Gqz{np&>N4)I2d+iA{#?a~x%n4X zD?3*7w0ddpbdkXmbZNv}20>Jqf4K~)1?Vyz$pz`$Yy?q%Kxj$fBF-Jt6vAu0ujm;) zyKZZ)rJqU#)^)fShsWz)k0x=2Jb^Y36$l(DrfkL6(rcIRKiMWwIt4yp_E=bYhf`uL z7aSHl0p}rDr^+i$T^D?(M$|kT6`0J06!~Q z;Yf6QC|rUfPdN3f_(wlU(NUoo;eqy@&KkF3DO3~zvhzoOdu}`$6Ei<%MTE*T3c9jq|Oo~X)RR@LnWX$->&f7 zy|94uqOzvyOv(CLK&QrH@`MSYDR68Ysm8%&lHSM(E}|K~`BIz)QgOrqp|a%t?1{HD zt~ll^y{{#iVWP&}lgjQ$op2u!O==HCf;ez!gcfK}#2+!JO6|HWNbl;++coAAE+huk zgfQzE`LoWlkcbzVd-5HEwDVbNtfc&I3XLO*y}ghW0!%aYqQ4}&^J z=lI*EAypoGk9JY6ZVZDDyiIh(RS8rQc_-mbl`T zE){MayzAa3GBqEWGW~8=+|Q*PZ`GRJ$=&hT+{j<{JdpPFZtqw#tlf;qd>O=tm;w|J zEkgS$ttiU3-0Wpb>2D!p?>)hqcCJfT-9vf-xP`{Dj3JWbqT15u!L0-mBpSLEQ zh}??eJ%A1J@LH#!iDWf~_(&f~A?XN^7_lU!8$%{>>Gpi~HiEFumh;w`jSXEDmHvHL z^W%ACi#h=wX*Lmo9oNjcS^*`36b@3?NqT$tn~Eu(9g#LRbqH|iOEsMM+PsP%fI1J- zcxr3ZwO#;Vd!_@UI^#M0&`;BZw{w$#UyduCDA!+SJ>W?U{d(;LTRc&YUO7Y!V=RvlT3EH3N2ooON26<>bG)dODAlYJSh@ zS0LkJZ;p2i;lUe|lbtE{NpY0C#P*?rD!&a^u{UBu0IwVTQ~Eb=FCJc`Q(5uZT;wR@ ziE6Y$4d7?IXI2A%Q?5!{JD!Kl8xYDXDS4U&Q{7M>)$0jyc{gd+A~&?29s8?wTs8w1 zblk0qpFVU4!9Xi@?Lz~H;1snOO7augp5ZDSeiT!DLDofDwk*@-XtucT&Hm%pe6=M3 z(YE?1z}Qu+-vYV6#&YYg{i|P~MwI7;V8v%-#q=4HO{i!Rji%ZOK19nkPnTmKANiMA zA*vfe>VA3&d~By8&-!bd5&OU4bp*Od6L +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + +<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> + + +<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellow", "#ffffcc"); %> + + + + + + + + + + +
+ +
+
+ + + + + +
+ +
+
+ + + + + +
+ +<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "yellow"); %> + diff --git a/source/web/jsp/dashboards/dashlets/my-completed-tasks.png b/source/web/jsp/dashboards/dashlets/my-completed-tasks.png new file mode 100644 index 0000000000000000000000000000000000000000..f53c1bbd046a68aa0979ee7f1daf520e102e4ca0 GIT binary patch literal 15407 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 +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + + diff --git a/source/web/jsp/dashboards/dashlets/my-tasks-todo.png b/source/web/jsp/dashboards/dashlets/my-tasks-todo.png new file mode 100644 index 0000000000000000000000000000000000000000..e34ceee2aac106b23650393c5a32c47fe804f74e GIT binary patch literal 15216 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 +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + + diff --git a/source/web/jsp/dashboards/dashlets/tasklist-todo.jsp b/source/web/jsp/dashboards/dashlets/tasklist-todo.jsp new file mode 100644 index 0000000000..22d7f0c020 --- /dev/null +++ b/source/web/jsp/dashboards/dashlets/tasklist-todo.jsp @@ -0,0 +1,22 @@ +<%-- + Copyright (C) 2006 Alfresco, Inc. + + Licensed under the Mozilla Public License version 1.1 + with a permitted attribution clause. You may obtain a + copy of the License at + + http://www.alfresco.org/legal/license.txt + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the + License. +--%> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + + diff --git a/source/web/jsp/dashboards/dummy.jsp b/source/web/jsp/dashboards/dummy.jsp new file mode 100644 index 0000000000..2893239647 --- /dev/null +++ b/source/web/jsp/dashboards/dummy.jsp @@ -0,0 +1,16 @@ +<%-- + Copyright (C) 2005 Alfresco, Inc. + + Licensed under the Mozilla Public License version 1.1 + with a permitted attribution clause. You may obtain a + copy of the License at + + http://www.alfresco.org/legal/license.txt + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the + License. +--%> \ No newline at end of file diff --git a/source/web/jsp/dashboards/layouts/narrow-left-2column.jsp b/source/web/jsp/dashboards/layouts/narrow-left-2column.jsp new file mode 100644 index 0000000000..37a2f2f8c7 --- /dev/null +++ b/source/web/jsp/dashboards/layouts/narrow-left-2column.jsp @@ -0,0 +1,84 @@ +<%-- + Copyright (C) 2006 Alfresco, Inc. + + Licensed under the Mozilla Public License version 1.1 + with a permitted attribution clause. You may obtain a + copy of the License at + + http://www.alfresco.org/legal/license.txt + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the + License. +--%> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + +<%@ page import="org.alfresco.web.app.Application" %> + + + <% Application.getDashboardManager().initDashboard(); %> + + + + + + +

+ + + + + +
+ + + + + +
+ + + + + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ diff --git a/source/web/jsp/dashboards/layouts/narrow-right-2column.jsp b/source/web/jsp/dashboards/layouts/narrow-right-2column.jsp new file mode 100644 index 0000000000..d56814c8ca --- /dev/null +++ b/source/web/jsp/dashboards/layouts/narrow-right-2column.jsp @@ -0,0 +1,84 @@ +<%-- + Copyright (C) 2006 Alfresco, Inc. + + Licensed under the Mozilla Public License version 1.1 + with a permitted attribution clause. You may obtain a + copy of the License at + + http://www.alfresco.org/legal/license.txt + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the + License. +--%> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + +<%@ page import="org.alfresco.web.app.Application" %> + + + <% Application.getDashboardManager().initDashboard(); %> + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+
diff --git a/source/web/jsp/dashboards/layouts/single-column.jsp b/source/web/jsp/dashboards/layouts/single-column.jsp new file mode 100644 index 0000000000..c9c597bdab --- /dev/null +++ b/source/web/jsp/dashboards/layouts/single-column.jsp @@ -0,0 +1,56 @@ +<%-- + Copyright (C) 2006 Alfresco, Inc. + + Licensed under the Mozilla Public License version 1.1 + with a permitted attribution clause. You may obtain a + copy of the License at + + http://www.alfresco.org/legal/license.txt + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the + License. +--%> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + +<%@ page import="org.alfresco.web.app.Application" %> + +<% Application.getDashboardManager().initDashboard(); %> + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/web/jsp/dashboards/layouts/three-column.jsp b/source/web/jsp/dashboards/layouts/three-column.jsp new file mode 100644 index 0000000000..586705cbe0 --- /dev/null +++ b/source/web/jsp/dashboards/layouts/three-column.jsp @@ -0,0 +1,113 @@ +<%-- + Copyright (C) 2006 Alfresco, Inc. + + Licensed under the Mozilla Public License version 1.1 + with a permitted attribution clause. You may obtain a + copy of the License at + + http://www.alfresco.org/legal/license.txt + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the + License. +--%> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + +<%@ page import="org.alfresco.web.app.Application" %> + + + <% Application.getDashboardManager().initDashboard(); %> + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+
diff --git a/source/web/jsp/dashboards/wizard/columns.jsp b/source/web/jsp/dashboards/wizard/columns.jsp new file mode 100644 index 0000000000..eb34724772 --- /dev/null +++ b/source/web/jsp/dashboards/wizard/columns.jsp @@ -0,0 +1,76 @@ +<%-- + Copyright (C) 2006 Alfresco, Inc. + + Licensed under the Mozilla Public License version 1.1 + with a permitted attribution clause. You may obtain a + copy of the License at + + http://www.alfresco.org/legal/license.txt + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the + License. +--%> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + +<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> + + + + + + + + +   + + + +   + + + + + + + + + <%-- note this component ID is referenced in DashboardWizard --%> + + + + + + + + + + + <%-- note this component ID is referenced in DashboardWizard --%> + + + + + +
+ +
+
+ +
+
+
diff --git a/source/web/jsp/dashboards/wizard/layout.jsp b/source/web/jsp/dashboards/wizard/layout.jsp new file mode 100644 index 0000000000..1433a08f43 --- /dev/null +++ b/source/web/jsp/dashboards/wizard/layout.jsp @@ -0,0 +1,56 @@ +<%-- + Copyright (C) 2006 Alfresco, Inc. + + Licensed under the Mozilla Public License version 1.1 + with a permitted attribution clause. You may obtain a + copy of the License at + + http://www.alfresco.org/legal/license.txt + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the + License. +--%> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + +<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> + + + + + + + + + + + <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %> + + + + + +
+ + + + + + + + + +
+ <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %> +
+
+ +
diff --git a/source/web/jsp/dialog/about.jsp b/source/web/jsp/dialog/about.jsp index 45bccbc610..34669e0241 100644 --- a/source/web/jsp/dialog/about.jsp +++ b/source/web/jsp/dialog/about.jsp @@ -158,6 +158,9 @@
+ + + diff --git a/source/web/jsp/dialog/delete-space.jsp b/source/web/jsp/dialog/delete-space.jsp deleted file mode 100644 index 2126763bb7..0000000000 --- a/source/web/jsp/dialog/delete-space.jsp +++ /dev/null @@ -1,173 +0,0 @@ -<%-- - Copyright (C) 2005 Alfresco, Inc. - - Licensed under the Mozilla Public License version 1.1 - with a permitted attribution clause. You may obtain a - copy of the License at - - http://www.alfresco.org/legal/license.txt - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - either express or implied. See the License for the specific - language governing permissions and limitations under the - License. ---%> -<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> -<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> -<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - -<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> -<%@ page isELIgnored="false" %> -<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> - - - - - - <%-- load a bundle of properties with I18N strings --%> - - - <%-- set the form name here --%> - - - <%-- Main outer table --%> - - - <%-- Title bar --%> - - - - - <%-- Main area --%> - - <%-- Shelf --%> - - - <%-- Work Area --%> - - -
- <%@ include file="../parts/titlebar.jsp" %> -
- <%@ include file="../parts/shelf.jsp" %> - - - <%-- Breadcrumb --%> - <%@ include file="../parts/breadcrumb.jsp" %> - - <%-- Status and Actions --%> - - - - - - - <%-- separator row with gradient shadow --%> - - - - - - - <%-- Details --%> - - - - - - - <%-- separator row with bottom panel graphics --%> - - - - - - -
- - <%-- Status and Actions inner contents table --%> - <%-- Generally this consists of an icon, textual summary and actions for the current object --%> - - - - - -
- - -
''
-
-
- -
- - - - - - - -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %> - - - - - - - - - - - -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellowInner", "#ffffcc"); %> - - - - - -
- -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "yellowInner"); %> -
- - - -
- <%-- Error Messages --%> - <%-- messages tag to show messages not handled by other specific message tags --%> - - -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %> -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> - - - - - - - - -
- -
- -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
-
-
- -
- -
- -
diff --git a/source/web/jsp/dialog/delete.jsp b/source/web/jsp/dialog/delete.jsp new file mode 100644 index 0000000000..d14067c888 --- /dev/null +++ b/source/web/jsp/dialog/delete.jsp @@ -0,0 +1,26 @@ +<%-- + Copyright (C) 2005 Alfresco, Inc. + + Licensed under the Mozilla Public License version 1.1 + with a permitted attribution clause. You may obtain a + copy of the License at + + http://www.alfresco.org/legal/license.txt + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the + License. +--%> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + +<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> +<%@ page isELIgnored="false" %> + + \ No newline at end of file diff --git a/source/web/jsp/wizard/create-content/create-text.jsp b/source/web/jsp/dialog/edit-space-category.jsp similarity index 70% rename from source/web/jsp/wizard/create-content/create-text.jsp rename to source/web/jsp/dialog/edit-space-category.jsp index 564def1d9e..f53b648b2b 100644 --- a/source/web/jsp/wizard/create-content/create-text.jsp +++ b/source/web/jsp/dialog/edit-space-category.jsp @@ -1,176 +1,169 @@ -<%-- - Copyright (C) 2005 Alfresco, Inc. - - Licensed under the Mozilla Public License version 1.1 - with a permitted attribution clause. You may obtain a - copy of the License at - - http://www.alfresco.org/legal/license.txt - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - either express or implied. See the License for the specific - language governing permissions and limitations under the - License. ---%> -<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> -<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> -<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - -<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> -<%@ page isELIgnored="false" %> -<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> - - - - - - <%-- load a bundle of properties with I18N strings --%> - - - <%-- set the form name here --%> - - - <%-- Main outer table --%> - - - <%-- Title bar --%> - - - - - <%-- Main area --%> - - <%-- Shelf --%> - - - <%-- Work Area --%> - - -
- <%@ include file="../../parts/titlebar.jsp" %> -
- <%@ include file="../../parts/shelf.jsp" %> - - - <%-- Breadcrumb --%> - <%@ include file="../../parts/breadcrumb.jsp" %> - - <%-- Status and Actions --%> - - - - - - - <%-- separator row with gradient shadow --%> - - - - - - - <%-- Details --%> - - - - - - - <%-- Error Messages --%> - - - - - - - <%-- separator row with bottom panel graphics --%> - - - - - - -
- - <%-- Status and Actions inner contents table --%> - <%-- Generally this consists of an icon, textual summary and actions for the current object --%> - - - - - -
- -
-
-
- -
- - - - - - - - -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> -
- - - - - - - <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
- - - - - - - <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> - - - - - - - - - - - - - - -
- -
- -
- -
- -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
-
- <%-- messages tag to show messages not handled by other specific message tags --%> - -
-
- -
- -
- +<%-- + Copyright (C) 2005 Alfresco, Inc. + + Licensed under the Mozilla Public License version 1.1 + with a permitted attribution clause. You may obtain a + copy of the License at + + http://www.alfresco.org/legal/license.txt + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the + License. +--%> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + +<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> +<%@ page isELIgnored="false" %> +<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> + + + + + + <%-- load a bundle of properties with I18N strings --%> + + + + + <%-- Main outer table --%> + + + <%-- Title bar --%> + + + + + <%-- Main area --%> + + <%-- Shelf --%> + + + <%-- Work Area --%> + + +
+ <%@ include file="../parts/titlebar.jsp" %> +
+ <%@ include file="../parts/shelf.jsp" %> + + + <%-- Breadcrumb --%> + <%@ include file="../parts/breadcrumb.jsp" %> + + <%-- Status and Actions --%> + + + + + + + <%-- separator row with gradient shadow --%> + + + + + + + <%-- Details --%> + + + + + + + <%-- Error Messages --%> + + + + + + + <%-- separator row with bottom panel graphics --%> + + + + + + +
+ + <%-- Status and Actions inner contents table --%> + <%-- Generally this consists of an icon, textual summary and actions for the current object --%> + + + + + +
+ +
''
+
+
+ +
+ + + + + + +
+ <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %> + + + + + + + +
: + + + +
+ <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %> +
+ <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> + + + + + + + + +
+ +
+ +
+ <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> +
+
+ <%-- messages tag to show messages not handled by other specific message tags --%> + +
+
+ +
+ +
+
\ No newline at end of file diff --git a/source/web/jsp/dialog/export.jsp b/source/web/jsp/dialog/export.jsp index 6d14a5a33e..b8891ed0ab 100644 --- a/source/web/jsp/dialog/export.jsp +++ b/source/web/jsp/dialog/export.jsp @@ -92,7 +92,7 @@
\ No newline at end of file diff --git a/source/web/jsp/users/change-password.jsp b/source/web/jsp/users/change-password.jsp index 87f9164f93..a2f5dc6e35 100644 --- a/source/web/jsp/users/change-password.jsp +++ b/source/web/jsp/users/change-password.jsp @@ -162,7 +162,7 @@ - + diff --git a/source/web/jsp/users/delete-user.jsp b/source/web/jsp/users/delete-user.jsp index b4cdf4ca4d..7030d0a549 100644 --- a/source/web/jsp/users/delete-user.jsp +++ b/source/web/jsp/users/delete-user.jsp @@ -126,7 +126,7 @@ - + diff --git a/source/web/jsp/forums/delete-forums.jsp b/source/web/jsp/users/user-console.jsp similarity index 53% rename from source/web/jsp/forums/delete-forums.jsp rename to source/web/jsp/users/user-console.jsp index b8784137a0..877c84bf6d 100644 --- a/source/web/jsp/forums/delete-forums.jsp +++ b/source/web/jsp/users/user-console.jsp @@ -24,15 +24,14 @@ <%@ page isELIgnored="false" %> <%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> - + <%-- load a bundle of properties with I18N strings --%> - <%-- set the form name here --%> - + <%-- Main outer table --%> @@ -61,17 +60,17 @@ -
- + <%-- Status and Actions inner contents table --%> <%-- Generally this consists of an icon, textual summary and actions for the current object --%> -
- + + -
''
-
+
+
@@ -90,45 +89,65 @@ <%-- Details --%>
- + @@ -170,4 +185,4 @@ - + \ No newline at end of file diff --git a/source/web/jsp/users/users.jsp b/source/web/jsp/users/users.jsp index cec237c38e..28839341af 100644 --- a/source/web/jsp/users/users.jsp +++ b/source/web/jsp/users/users.jsp @@ -189,11 +189,11 @@ - + - + @@ -211,7 +211,7 @@
+ + - +
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %> - - - - - - - - - - - -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellowInner", "#ffffcc"); %> - - - - - -
- -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "yellowInner"); %> -
- - - -
- <%-- Error Messages --%> - <%-- messages tag to show messages not handled by other specific message tags --%> - - -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %> + <%-- wrapper comment used by the panel to add additional component facets --%> + + + <%----%> + + <%----%> + + + + + + + + + + + + + + + + +
+ : + + +
+ : + + +
+ : + + +
+
+ <%-- context for current user is setup on entry to user console --%> + +
+
+ + + + <%----%> + + <%----%> + + + + +
+
@@ -136,20 +155,16 @@ - - - -
- -
- +
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %>
+
- +
diff --git a/source/web/jsp/wizard/add-content/properties.jsp b/source/web/jsp/wizard/add-content/properties.jsp deleted file mode 100644 index cc7736519d..0000000000 --- a/source/web/jsp/wizard/add-content/properties.jsp +++ /dev/null @@ -1,267 +0,0 @@ -<%-- - Copyright (C) 2005 Alfresco, Inc. - - Licensed under the Mozilla Public License version 1.1 - with a permitted attribution clause. You may obtain a - copy of the License at - - http://www.alfresco.org/legal/license.txt - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - either express or implied. See the License for the specific - language governing permissions and limitations under the - License. ---%> -<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> -<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> -<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - -<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> -<%@ page isELIgnored="false" %> -<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> - - - - - - - - <%-- load a bundle of properties with I18N strings --%> - - - - - <%-- Main outer table --%> - - - <%-- Title bar --%> - - - - - <%-- Main area --%> - - <%-- Shelf --%> - - - <%-- Work Area --%> - - -
- <%@ include file="../../parts/titlebar.jsp" %> -
- <%@ include file="../../parts/shelf.jsp" %> - - - <%-- Breadcrumb --%> - <%@ include file="../../parts/breadcrumb.jsp" %> - - <%-- Status and Actions --%> - - - - - - - <%-- separator row with gradient shadow --%> - - - - - - - <%-- Details --%> - - - - - - - <%-- separator row with bottom panel graphics --%> - - - - - - -
- - <%-- Status and Actions inner contents table --%> - <%-- Generally this consists of an icon, textual summary and actions for the current object --%> - - - - - -
- -
-
-
- -
- - - - - - - -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> -
- - - - - - <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
- - - - <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
: -  * -
: - - -  * -
: - - -  * -
: -  * -
: - -
: - -
- - - - - - - -
 
-
-   - -
-
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %> -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> - - - - - - - - - - - - - - -
- -
- -
- -
- -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
-
-
- -
- -
- -
\ No newline at end of file diff --git a/source/web/jsp/wizard/add-content/summary.jsp b/source/web/jsp/wizard/add-content/summary.jsp deleted file mode 100644 index c788f0189b..0000000000 --- a/source/web/jsp/wizard/add-content/summary.jsp +++ /dev/null @@ -1,173 +0,0 @@ -<%-- - Copyright (C) 2005 Alfresco, Inc. - - Licensed under the Mozilla Public License version 1.1 - with a permitted attribution clause. You may obtain a - copy of the License at - - http://www.alfresco.org/legal/license.txt - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - either express or implied. See the License for the specific - language governing permissions and limitations under the - License. ---%> -<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> -<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> -<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - -<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> -<%@ page isELIgnored="false" %> -<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> - - - - - - <%-- load a bundle of properties with I18N strings --%> - - - - - <%-- Main outer table --%> - - - <%-- Title bar --%> - - - - - <%-- Main area --%> - - <%-- Shelf --%> - - - <%-- Work Area --%> - - -
- <%@ include file="../../parts/titlebar.jsp" %> -
- <%@ include file="../../parts/shelf.jsp" %> - - - <%-- Breadcrumb --%> - <%@ include file="../../parts/breadcrumb.jsp" %> - - <%-- Status and Actions --%> - - - - - - - <%-- separator row with gradient shadow --%> - - - - - - - <%-- Details --%> - - - - - - - <%-- separator row with bottom panel graphics --%> - - - - - - -
- - <%-- Status and Actions inner contents table --%> - <%-- Generally this consists of an icon, textual summary and actions for the current object --%> - - - - - -
- -
-
-
- -
- - - - - - - - -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> -
- - - - - - <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
- - - - <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %> - - - - - - - - - - - - - -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %> -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> - - - - - - - - - - - -
- -
- -
- -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
-
-
- -
- -
- -
\ No newline at end of file diff --git a/source/web/jsp/wizard/add-content/upload.jsp b/source/web/jsp/wizard/add-content/upload.jsp deleted file mode 100644 index 3dbb6aa678..0000000000 --- a/source/web/jsp/wizard/add-content/upload.jsp +++ /dev/null @@ -1,212 +0,0 @@ -<%-- - Copyright (C) 2005 Alfresco, Inc. - - Licensed under the Mozilla Public License version 1.1 - with a permitted attribution clause. You may obtain a - copy of the License at - - http://www.alfresco.org/legal/license.txt - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - either express or implied. See the License for the specific - language governing permissions and limitations under the - License. ---%> -<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> -<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> -<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - -<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> -<%@ page isELIgnored="false" %> -<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> -<%@ page import="org.alfresco.web.bean.wizard.AddContentWizard" %> -<%@ page import="org.alfresco.web.app.Application" %> -<%@ page import="org.alfresco.web.app.servlet.FacesHelper" %> -<%@ page import="javax.faces.context.FacesContext" %> - - - - - - <%-- load a bundle of properties with I18N strings --%> - - - - - <%-- Main outer table --%> - - - <%-- Title bar --%> - - - - - <%-- Main area --%> - - <%-- Shelf --%> - - - <%-- Work Area --%> - - -
- <%@ include file="../../parts/titlebar.jsp" %> -
- <%@ include file="../../parts/shelf.jsp" %> - - - <%-- Breadcrumb --%> - <%@ include file="../../parts/breadcrumb.jsp" %> - - <%-- Status and Actions --%> - - - - - - - <%-- separator row with gradient shadow --%> - - - - - - - <%-- Details --%> - - - - - - - <%-- separator row with bottom panel graphics --%> - - - - - - -
- - <%-- Status and Actions inner contents table --%> - <%-- Generally this consists of an icon, textual summary and actions for the current object --%> - - - - - -
- -
-
-
- -
- - - - - - - - - -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> -
- - - - - - <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
- - - - <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <% - AddContentWizard wiz = (AddContentWizard)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "AddContentWizard"); - if (wiz != null && wiz.getFileName() != null) { - %> - - - - <% } %> - - - - -
1.
- : -
2.
- " /> -
===TEST JSP===
- - <%=wiz.getFileUploadSuccessMsg()%> -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %> -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> - - - - - - - - - - - -
- -
- -
- -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
-
-
- -
- -
- -
\ No newline at end of file diff --git a/source/web/jsp/wizard/container.jsp b/source/web/jsp/wizard/container.jsp index 64d64be191..fdaa72d1b4 100644 --- a/source/web/jsp/wizard/container.jsp +++ b/source/web/jsp/wizard/container.jsp @@ -163,7 +163,7 @@
+ action="#{WizardManager.cancel}" immediate="true" />
diff --git a/source/web/jsp/wizard/create-content/create-html.jsp b/source/web/jsp/wizard/create-content/create-html.jsp deleted file mode 100644 index 8b7e82f0c0..0000000000 --- a/source/web/jsp/wizard/create-content/create-html.jsp +++ /dev/null @@ -1,208 +0,0 @@ -<%-- - Copyright (C) 2005 Alfresco, Inc. - - Licensed under the Mozilla Public License version 1.1 - with a permitted attribution clause. You may obtain a - copy of the License at - - http://www.alfresco.org/legal/license.txt - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - either express or implied. See the License for the specific - language governing permissions and limitations under the - License. ---%> -<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> -<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> -<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - -<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> -<%@ page isELIgnored="false" %> -<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> - - - - - - - - - - <%-- load a bundle of properties with I18N strings --%> - - - <%-- set the form name here --%> - - - <%-- Main outer table --%> - - - <%-- Title bar --%> - - - - - <%-- Main area --%> - - <%-- Shelf --%> - - - <%-- Work Area --%> - - -
- <%@ include file="../../parts/titlebar.jsp" %> -
- <%@ include file="../../parts/shelf.jsp" %> - - - <%-- Breadcrumb --%> - <%@ include file="../../parts/breadcrumb.jsp" %> - - <%-- Status and Actions --%> - - - - - - - <%-- separator row with gradient shadow --%> - - - - - - - <%-- Details --%> - - - - - - - <%-- Error Messages --%> - - - - - - - <%-- separator row with bottom panel graphics --%> - - - - - - -
- - <%-- Status and Actions inner contents table --%> - <%-- Generally this consists of an icon, textual summary and actions for the current object --%> - - - - - -
- -
-
-
- -
- - - - - - - - -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> -
- - - - - - - <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
- - - -
- -
- - -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> - - - - - - - - - - - - - - -
- -
- -
- -
- -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
-
- <%-- messages tag to show messages not handled by other specific message tags --%> - -
-
- -
- -
- -
\ No newline at end of file diff --git a/source/web/jsp/wizard/create-content/properties.jsp b/source/web/jsp/wizard/create-content/properties.jsp deleted file mode 100644 index af92e807f2..0000000000 --- a/source/web/jsp/wizard/create-content/properties.jsp +++ /dev/null @@ -1,251 +0,0 @@ -<%-- - Copyright (C) 2005 Alfresco, Inc. - - Licensed under the Mozilla Public License version 1.1 - with a permitted attribution clause. You may obtain a - copy of the License at - - http://www.alfresco.org/legal/license.txt - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - either express or implied. See the License for the specific - language governing permissions and limitations under the - License. ---%> -<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> -<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> -<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - -<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> -<%@ page isELIgnored="false" %> -<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> - - - - - - - - <%-- load a bundle of properties with I18N strings --%> - - - <%-- set the form name here --%> - - - <%-- Main outer table --%> - - - <%-- Title bar --%> - - - - - <%-- Main area --%> - - <%-- Shelf --%> - - - <%-- Work Area --%> - - -
- <%@ include file="../../parts/titlebar.jsp" %> -
- <%@ include file="../../parts/shelf.jsp" %> - - - <%-- Breadcrumb --%> - <%@ include file="../../parts/breadcrumb.jsp" %> - - <%-- Status and Actions --%> - - - - - - - <%-- separator row with gradient shadow --%> - - - - - - - <%-- Details --%> - - - - - - - <%-- separator row with bottom panel graphics --%> - - - - - - -
- - <%-- Status and Actions inner contents table --%> - <%-- Generally this consists of an icon, textual summary and actions for the current object --%> - - - - - -
- -
-
-
- -
- - - - - - - -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> -
- - - - - - - <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
- - - - <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
: -  * -
: - - -  * -
: - - -  * -
: -  * -
: - -
: - -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %> -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> - - - - - - - - - - - - - - -
- -
- -
- -
- -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
-
-
- -
- -
- - - -
\ No newline at end of file diff --git a/source/web/jsp/wizard/create-content/select-type.jsp b/source/web/jsp/wizard/create-content/select-type.jsp deleted file mode 100644 index b0776acecf..0000000000 --- a/source/web/jsp/wizard/create-content/select-type.jsp +++ /dev/null @@ -1,191 +0,0 @@ -<%-- - Copyright (C) 2005 Alfresco, Inc. - - Licensed under the Mozilla Public License version 1.1 - with a permitted attribution clause. You may obtain a - copy of the License at - - http://www.alfresco.org/legal/license.txt - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - either express or implied. See the License for the specific - language governing permissions and limitations under the - License. ---%> -<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> -<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> -<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - -<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> -<%@ page isELIgnored="false" %> -<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> - - - - - - <%-- load a bundle of properties with I18N strings --%> - - - <%-- set the form name here --%> - - - <%-- Main outer table --%> - - - <%-- Title bar --%> - - - - - <%-- Main area --%> - - <%-- Shelf --%> - - - <%-- Work Area --%> - - -
- <%@ include file="../../parts/titlebar.jsp" %> -
- <%@ include file="../../parts/shelf.jsp" %> - - - <%-- Breadcrumb --%> - <%@ include file="../../parts/breadcrumb.jsp" %> - - <%-- Status and Actions --%> - - - - - - - <%-- separator row with gradient shadow --%> - - - - - - - <%-- Details --%> - - - - - - - <%-- Error Messages --%> - - - - - - - <%-- separator row with bottom panel graphics --%> - - - - - - -
- - <%-- Status and Actions inner contents table --%> - <%-- Generally this consists of an icon, textual summary and actions for the current object --%> - - - - - -
- -
-
-
- -
- - - - - - - - -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> -
- - - - - - - <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %> - - - - - - - - - - - - - - - - - -
- - - - -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %> -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> - - - - - - - - - - - -
- -
- -
- -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> -
-
- <%-- messages tag to show messages not handled by other specific message tags --%> - -
-
- -
- -
- -
\ No newline at end of file diff --git a/source/web/jsp/wizard/summary.jsp b/source/web/jsp/wizard/summary.jsp index 3a70c45eeb..2472e7c75d 100644 --- a/source/web/jsp/wizard/summary.jsp +++ b/source/web/jsp/wizard/summary.jsp @@ -20,4 +20,8 @@ <%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> <%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - \ No newline at end of file + + + \ No newline at end of file diff --git a/source/web/scripts/ajax/common.js b/source/web/scripts/ajax/common.js new file mode 100644 index 0000000000..0675817a56 --- /dev/null +++ b/source/web/scripts/ajax/common.js @@ -0,0 +1,22 @@ +// +// Alfresco AJAX support library +// Gavin Cornwell 14-07-2006 +// + +/** + * Default handler for errors + */ +function handleErrorDojo(type, errObj) +{ + // remove the dojo prefix from the message + var errorStart = "XMLHttpTransport Error: 500 "; + var msg = errObj.message; + + if (msg.indexOf(errorStart) != -1) + { + msg = msg.substring(errorStart.length); + } + + // TODO: Show a nicer error page, an alert will do for now! + alert(msg); +} \ No newline at end of file diff --git a/source/web/scripts/ajax/dojo.js b/source/web/scripts/ajax/dojo.js new file mode 100644 index 0000000000..038afe584f --- /dev/null +++ b/source/web/scripts/ajax/dojo.js @@ -0,0 +1,5593 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +/* + This is a compiled version of Dojo, built for deployment and not for + development. To get an editable version, please visit: + + http://dojotoolkit.org + + for documentation and information on getting the source. +*/ + +if(typeof dojo=="undefined"){ +var dj_global=this; +function dj_undef(_1,_2){ +if(_2==null){ +_2=dj_global; +} +return (typeof _2[_1]=="undefined"); +} +if(dj_undef("djConfig")){ +var djConfig={}; +} +if(dj_undef("dojo")){ +var dojo={}; +} +dojo.version={major:0,minor:3,patch:1,flag:"",revision:Number("$Rev: 4342 $".match(/[0-9]+/)[0]),toString:function(){ +with(dojo.version){ +return major+"."+minor+"."+patch+flag+" ("+revision+")"; +} +}}; +dojo.evalProp=function(_3,_4,_5){ +return (_4&&!dj_undef(_3,_4)?_4[_3]:(_5?(_4[_3]={}):undefined)); +}; +dojo.parseObjPath=function(_6,_7,_8){ +var _9=(_7!=null?_7:dj_global); +var _a=_6.split("."); +var _b=_a.pop(); +for(var i=0,l=_a.length;i1){ +dh.modulesLoadedListeners.push(function(){ +obj[_3d](); +}); +} +} +if(dh.post_load_&&dh.inFlightCount==0&&!dh.loadNotifying){ +dh.callLoaded(); +} +}; +dojo.addOnUnload=function(obj,_40){ +var dh=dojo.hostenv; +if(arguments.length==1){ +dh.unloadListeners.push(obj); +}else{ +if(arguments.length>1){ +dh.unloadListeners.push(function(){ +obj[_40](); +}); +} +} +}; +dojo.hostenv.modulesLoaded=function(){ +if(this.post_load_){ +return; +} +if((this.loadUriStack.length==0)&&(this.getTextStack.length==0)){ +if(this.inFlightCount>0){ +dojo.debug("files still in flight!"); +return; +} +dojo.hostenv.callLoaded(); +} +}; +dojo.hostenv.callLoaded=function(){ +if(typeof setTimeout=="object"){ +setTimeout("dojo.hostenv.loaded();",0); +}else{ +dojo.hostenv.loaded(); +} +}; +dojo.hostenv.getModuleSymbols=function(_42){ +var _43=_42.split("."); +for(var i=_43.length-1;i>0;i--){ +var _45=_43.slice(0,i).join("."); +var _46=this.getModulePrefix(_45); +if(_46!=_45){ +_43.splice(0,i,_46); +break; +} +} +return _43; +}; +dojo.hostenv._global_omit_module_check=false; +dojo.hostenv.loadModule=function(_47,_48,_49){ +if(!_47){ +return; +} +_49=this._global_omit_module_check||_49; +var _4a=this.findModule(_47,false); +if(_4a){ +return _4a; +} +if(dj_undef(_47,this.loading_modules_)){ +this.addedToLoadingCount.push(_47); +} +this.loading_modules_[_47]=1; +var _4b=_47.replace(/\./g,"/")+".js"; +var _4c=this.getModuleSymbols(_47); +var _4d=((_4c[0].charAt(0)!="/")&&(!_4c[0].match(/^\w+:/))); +var _4e=_4c[_4c.length-1]; +var _4f=_47.split("."); +if(_4e=="*"){ +_47=(_4f.slice(0,-1)).join("."); +while(_4c.length){ +_4c.pop(); +_4c.push(this.pkgFileName); +_4b=_4c.join("/")+".js"; +if(_4d&&(_4b.charAt(0)=="/")){ +_4b=_4b.slice(1); +} +ok=this.loadPath(_4b,((!_49)?_47:null)); +if(ok){ +break; +} +_4c.pop(); +} +}else{ +_4b=_4c.join("/")+".js"; +_47=_4f.join("."); +var ok=this.loadPath(_4b,((!_49)?_47:null)); +if((!ok)&&(!_48)){ +_4c.pop(); +while(_4c.length){ +_4b=_4c.join("/")+".js"; +ok=this.loadPath(_4b,((!_49)?_47:null)); +if(ok){ +break; +} +_4c.pop(); +_4b=_4c.join("/")+"/"+this.pkgFileName+".js"; +if(_4d&&(_4b.charAt(0)=="/")){ +_4b=_4b.slice(1); +} +ok=this.loadPath(_4b,((!_49)?_47:null)); +if(ok){ +break; +} +} +} +if((!ok)&&(!_49)){ +dojo.raise("Could not load '"+_47+"'; last tried '"+_4b+"'"); +} +} +if(!_49&&!this["isXDomain"]){ +_4a=this.findModule(_47,false); +if(!_4a){ +dojo.raise("symbol '"+_47+"' is not defined after loading '"+_4b+"'"); +} +} +return _4a; +}; +dojo.hostenv.startPackage=function(_51){ +var _52=dojo.evalObjPath((_51.split(".").slice(0,-1)).join(".")); +this.loaded_modules_[(new String(_51)).toLowerCase()]=_52; +var _53=_51.split(/\./); +if(_53[_53.length-1]=="*"){ +_53.pop(); +} +return dojo.evalObjPath(_53.join("."),true); +}; +dojo.hostenv.findModule=function(_54,_55){ +var lmn=(new String(_54)).toLowerCase(); +if(this.loaded_modules_[lmn]){ +return this.loaded_modules_[lmn]; +} +var _57=dojo.evalObjPath(_54); +if((_54)&&(typeof _57!="undefined")&&(_57)){ +this.loaded_modules_[lmn]=_57; +return _57; +} +if(_55){ +dojo.raise("no loaded module named '"+_54+"'"); +} +return null; +}; +dojo.kwCompoundRequire=function(_58){ +var _59=_58["common"]||[]; +var _5a=(_58[dojo.hostenv.name_])?_59.concat(_58[dojo.hostenv.name_]||[]):_59.concat(_58["default"]||[]); +for(var x=0;x<_5a.length;x++){ +var _5c=_5a[x]; +if(_5c.constructor==Array){ +dojo.hostenv.loadModule.apply(dojo.hostenv,_5c); +}else{ +dojo.hostenv.loadModule(_5c); +} +} +}; +dojo.require=function(){ +dojo.hostenv.loadModule.apply(dojo.hostenv,arguments); +}; +dojo.requireIf=function(){ +if((arguments[0]===true)||(arguments[0]=="common")||(arguments[0]&&dojo.render[arguments[0]].capable)){ +var _5d=[]; +for(var i=1;i1){ +var _67=_66[1]; +var _68=_67.split("&"); +for(var x in _68){ +var sp=_68[x].split("="); +if((sp[0].length>9)&&(sp[0].substr(0,9)=="djConfig.")){ +var opt=sp[0].substr(9); +try{ +djConfig[opt]=eval(sp[1]); +} +catch(e){ +djConfig[opt]=sp[1]; +} +} +} +} +} +if(((djConfig["baseScriptUri"]=="")||(djConfig["baseRelativePath"]==""))&&(document&&document.getElementsByTagName)){ +var _6c=document.getElementsByTagName("script"); +var _6d=/(__package__|dojo|bootstrap1)\.js([\?\.]|$)/i; +for(var i=0;i<_6c.length;i++){ +var src=_6c[i].getAttribute("src"); +if(!src){ +continue; +} +var m=src.match(_6d); +if(m){ +var _71=src.substring(0,m.index); +if(src.indexOf("bootstrap1")>-1){ +_71+="../"; +} +if(!this["djConfig"]){ +djConfig={}; +} +if(djConfig["baseScriptUri"]==""){ +djConfig["baseScriptUri"]=_71; +} +if(djConfig["baseRelativePath"]==""){ +djConfig["baseRelativePath"]=_71; +} +break; +} +} +} +var dr=dojo.render; +var drh=dojo.render.html; +var drs=dojo.render.svg; +var dua=drh.UA=navigator.userAgent; +var dav=drh.AV=navigator.appVersion; +var t=true; +var f=false; +drh.capable=t; +drh.support.builtin=t; +dr.ver=parseFloat(drh.AV); +dr.os.mac=dav.indexOf("Macintosh")>=0; +dr.os.win=dav.indexOf("Windows")>=0; +dr.os.linux=dav.indexOf("X11")>=0; +drh.opera=dua.indexOf("Opera")>=0; +drh.khtml=(dav.indexOf("Konqueror")>=0)||(dav.indexOf("Safari")>=0); +drh.safari=dav.indexOf("Safari")>=0; +var _79=dua.indexOf("Gecko"); +drh.mozilla=drh.moz=(_79>=0)&&(!drh.khtml); +if(drh.mozilla){ +drh.geckoVersion=dua.substring(_79+6,_79+14); +} +drh.ie=(document.all)&&(!drh.opera); +drh.ie50=drh.ie&&dav.indexOf("MSIE 5.0")>=0; +drh.ie55=drh.ie&&dav.indexOf("MSIE 5.5")>=0; +drh.ie60=drh.ie&&dav.indexOf("MSIE 6.0")>=0; +drh.ie70=drh.ie&&dav.indexOf("MSIE 7.0")>=0; +dojo.locale=(drh.ie?navigator.userLanguage:navigator.language).toLowerCase(); +dr.vml.capable=drh.ie; +drs.capable=f; +drs.support.plugin=f; +drs.support.builtin=f; +if(document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("org.w3c.dom.svg","1.0")){ +drs.capable=t; +drs.support.builtin=t; +drs.support.plugin=f; +} +})(); +dojo.hostenv.startPackage("dojo.hostenv"); +dojo.render.name=dojo.hostenv.name_="browser"; +dojo.hostenv.searchIds=[]; +dojo.hostenv._XMLHTTP_PROGIDS=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"]; +dojo.hostenv.getXmlhttpObject=function(){ +var _7a=null; +var _7b=null; +try{ +_7a=new XMLHttpRequest(); +} +catch(e){ +} +if(!_7a){ +for(var i=0;i<3;++i){ +var _7d=dojo.hostenv._XMLHTTP_PROGIDS[i]; +try{ +_7a=new ActiveXObject(_7d); +} +catch(e){ +_7b=e; +} +if(_7a){ +dojo.hostenv._XMLHTTP_PROGIDS=[_7d]; +break; +} +} +} +if(!_7a){ +return dojo.raise("XMLHTTP not available",_7b); +} +return _7a; +}; +dojo.hostenv.getText=function(uri,_7f,_80){ +var _81=this.getXmlhttpObject(); +if(_7f){ +_81.onreadystatechange=function(){ +if(4==_81.readyState){ +if((!_81["status"])||((200<=_81.status)&&(300>_81.status))){ +_7f(_81.responseText); +} +} +}; +} +_81.open("GET",uri,_7f?true:false); +try{ +_81.send(null); +if(_7f){ +return null; +} +if((_81["status"])&&((200>_81.status)||(300<=_81.status))){ +throw Error("Unable to load "+uri+" status:"+_81.status); +} +} +catch(e){ +if((_80)&&(!_7f)){ +return null; +}else{ +throw e; +} +} +return _81.responseText; +}; +dojo.hostenv.defaultDebugContainerId="dojoDebug"; +dojo.hostenv._println_buffer=[]; +dojo.hostenv._println_safe=false; +dojo.hostenv.println=function(_82){ +if(!dojo.hostenv._println_safe){ +dojo.hostenv._println_buffer.push(_82); +}else{ +try{ +var _83=document.getElementById(djConfig.debugContainerId?djConfig.debugContainerId:dojo.hostenv.defaultDebugContainerId); +if(!_83){ +_83=document.getElementsByTagName("body")[0]||document.body; +} +var div=document.createElement("div"); +div.appendChild(document.createTextNode(_82)); +_83.appendChild(div); +} +catch(e){ +try{ +document.write("
"+_82+"
"); +} +catch(e2){ +window.status=_82; +} +} +} +}; +dojo.addOnLoad(function(){ +dojo.hostenv._println_safe=true; +while(dojo.hostenv._println_buffer.length>0){ +dojo.hostenv.println(dojo.hostenv._println_buffer.shift()); +} +}); +function dj_addNodeEvtHdlr(_85,_86,fp,_88){ +var _89=_85["on"+_86]||function(){ +}; +_85["on"+_86]=function(){ +fp.apply(_85,arguments); +_89.apply(_85,arguments); +}; +return true; +} +dj_addNodeEvtHdlr(window,"load",function(){ +if(arguments.callee.initialized){ +return; +} +arguments.callee.initialized=true; +var _8a=function(){ +if(dojo.render.html.ie){ +dojo.hostenv.makeWidgets(); +} +}; +if(dojo.hostenv.inFlightCount==0){ +_8a(); +dojo.hostenv.modulesLoaded(); +}else{ +dojo.addOnLoad(_8a); +} +}); +dj_addNodeEvtHdlr(window,"unload",function(){ +dojo.hostenv.unloaded(); +}); +dojo.hostenv.makeWidgets=function(){ +var _8b=[]; +if(djConfig.searchIds&&djConfig.searchIds.length>0){ +_8b=_8b.concat(djConfig.searchIds); +} +if(dojo.hostenv.searchIds&&dojo.hostenv.searchIds.length>0){ +_8b=_8b.concat(dojo.hostenv.searchIds); +} +if((djConfig.parseWidgets)||(_8b.length>0)){ +if(dojo.evalObjPath("dojo.widget.Parse")){ +var _8c=new dojo.xml.Parse(); +if(_8b.length>0){ +for(var x=0;x<_8b.length;x++){ +var _8e=document.getElementById(_8b[x]); +if(!_8e){ +continue; +} +var _8f=_8c.parseElement(_8e,null,true); +dojo.widget.getParser().createComponents(_8f); +} +}else{ +if(djConfig.parseWidgets){ +var _8f=_8c.parseElement(document.getElementsByTagName("body")[0]||document.body,null,true); +dojo.widget.getParser().createComponents(_8f); +} +} +} +} +}; +dojo.addOnLoad(function(){ +if(!dojo.render.html.ie){ +dojo.hostenv.makeWidgets(); +} +}); +try{ +if(dojo.render.html.ie){ +document.write(""); +document.write(""); +} +} +catch(e){ +} +dojo.hostenv.writeIncludes=function(){ +}; +dojo.byId=function(id,doc){ +if(id&&(typeof id=="string"||id instanceof String)){ +if(!doc){ +doc=document; +} +return doc.getElementById(id); +} +return id; +}; +(function(){ +if(typeof dj_usingBootstrap!="undefined"){ +return; +} +var _92=false; +var _93=false; +var _94=false; +if((typeof this["load"]=="function")&&((typeof this["Packages"]=="function")||(typeof this["Packages"]=="object"))){ +_92=true; +}else{ +if(typeof this["load"]=="function"){ +_93=true; +}else{ +if(window.widget){ +_94=true; +} +} +} +var _95=[]; +if((this["djConfig"])&&((djConfig["isDebug"])||(djConfig["debugAtAllCosts"]))){ +_95.push("debug.js"); +} +if((this["djConfig"])&&(djConfig["debugAtAllCosts"])&&(!_92)&&(!_94)){ +_95.push("browser_debug.js"); +} +if((this["djConfig"])&&(djConfig["compat"])){ +_95.push("compat/"+djConfig["compat"]+".js"); +} +var _96=djConfig["baseScriptUri"]; +if((this["djConfig"])&&(djConfig["baseLoaderUri"])){ +_96=djConfig["baseLoaderUri"]; +} +for(var x=0;x<_95.length;x++){ +var _98=_96+"src/"+_95[x]; +if(_92||_93){ +load(_98); +}else{ +try{ +document.write(""); +} +catch(e){ +var _99=document.createElement("script"); +_99.src=_98; +document.getElementsByTagName("head")[0].appendChild(_99); +} +} +} +})(); +dojo.fallback_locale="en"; +dojo.normalizeLocale=function(_9a){ +return _9a?_9a.toLowerCase():dojo.locale; +}; +dojo.requireLocalization=function(_9b,_9c,_9d){ +dojo.debug("EXPERIMENTAL: dojo.requireLocalization"); +var _9e=dojo.hostenv.getModuleSymbols(_9b); +var _9f=_9e.concat("nls").join("/"); +_9d=dojo.normalizeLocale(_9d); +var _a0=_9d.split("-"); +var _a1=[]; +for(var i=_a0.length;i>0;i--){ +_a1.push(_a0.slice(0,i).join("-")); +} +if(_a1[_a1.length-1]!=dojo.fallback_locale){ +_a1.push(dojo.fallback_locale); +} +var _a3=[_9b,"_nls",_9c].join("."); +var _a4=dojo.hostenv.startPackage(_a3); +dojo.hostenv.loaded_modules_[_a3]=_a4; +var _a5=false; +for(var i=_a1.length-1;i>=0;i--){ +var loc=_a1[i]; +var pkg=[_a3,loc].join("."); +var _a8=false; +if(!dojo.hostenv.findModule(pkg)){ +dojo.hostenv.loaded_modules_[pkg]=null; +var _a9=[_9f,loc,_9c].join("/")+".js"; +_a8=dojo.hostenv.loadPath(_a9,null,function(_aa){ +_a4[loc]=_aa; +if(_a5){ +for(var x in _a5){ +if(!_a4[loc][x]){ +_a4[loc][x]=_a5[x]; +} +} +} +}); +}else{ +_a8=true; +} +if(_a8&&_a4[loc]){ +_a5=_a4[loc]; +} +} +}; +dojo.provide("dojo.string.common"); +dojo.require("dojo.string"); +dojo.string.trim=function(str,wh){ +if(!str.replace){ +return str; +} +if(!str.length){ +return str; +} +var re=(wh>0)?(/^\s+/):(wh<0)?(/\s+$/):(/^\s+|\s+$/g); +return str.replace(re,""); +}; +dojo.string.trimStart=function(str){ +return dojo.string.trim(str,1); +}; +dojo.string.trimEnd=function(str){ +return dojo.string.trim(str,-1); +}; +dojo.string.repeat=function(str,_b2,_b3){ +var out=""; +for(var i=0;i<_b2;i++){ +out+=str; +if(_b3&&i<_b2-1){ +out+=_b3; +} +} +return out; +}; +dojo.string.pad=function(str,len,c,dir){ +var out=String(str); +if(!c){ +c="0"; +} +if(!dir){ +dir=1; +} +while(out.length0){ +out=c+out; +}else{ +out+=c; +} +} +return out; +}; +dojo.string.padLeft=function(str,len,c){ +return dojo.string.pad(str,len,c,1); +}; +dojo.string.padRight=function(str,len,c){ +return dojo.string.pad(str,len,c,-1); +}; +dojo.provide("dojo.string"); +dojo.require("dojo.string.common"); +dojo.provide("dojo.lang.common"); +dojo.require("dojo.lang"); +dojo.lang._mixin=function(obj,_c2){ +var _c3={}; +for(var x in _c2){ +if(typeof _c3[x]=="undefined"||_c3[x]!=_c2[x]){ +obj[x]=_c2[x]; +} +} +if(dojo.render.html.ie&&dojo.lang.isFunction(_c2["toString"])&&_c2["toString"]!=obj["toString"]){ +obj.toString=_c2.toString; +} +return obj; +}; +dojo.lang.mixin=function(obj,_c6){ +for(var i=1,l=arguments.length;i-1; +}; +dojo.lang.isObject=function(wh){ +if(typeof wh=="undefined"){ +return false; +} +return (typeof wh=="object"||wh===null||dojo.lang.isArray(wh)||dojo.lang.isFunction(wh)); +}; +dojo.lang.isArray=function(wh){ +return (wh instanceof Array||typeof wh=="array"); +}; +dojo.lang.isArrayLike=function(wh){ +if(dojo.lang.isString(wh)){ +return false; +} +if(dojo.lang.isFunction(wh)){ +return false; +} +if(dojo.lang.isArray(wh)){ +return true; +} +if(typeof wh!="undefined"&&wh&&dojo.lang.isNumber(wh.length)&&isFinite(wh.length)){ +return true; +} +return false; +}; +dojo.lang.isFunction=function(wh){ +if(!wh){ +return false; +} +return (wh instanceof Function||typeof wh=="function"); +}; +dojo.lang.isString=function(wh){ +return (wh instanceof String||typeof wh=="string"); +}; +dojo.lang.isAlien=function(wh){ +if(!wh){ +return false; +} +return !dojo.lang.isFunction()&&/\{\s*\[native code\]\s*\}/.test(String(wh)); +}; +dojo.lang.isBoolean=function(wh){ +return (wh instanceof Boolean||typeof wh=="boolean"); +}; +dojo.lang.isNumber=function(wh){ +return (wh instanceof Number||typeof wh=="number"); +}; +dojo.lang.isUndefined=function(wh){ +return ((wh==undefined)&&(typeof wh=="undefined")); +}; +dojo.provide("dojo.lang.extras"); +dojo.require("dojo.lang.common"); +dojo.lang.setTimeout=function(_e2,_e3){ +var _e4=window,argsStart=2; +if(!dojo.lang.isFunction(_e2)){ +_e4=_e2; +_e2=_e3; +_e3=arguments[2]; +argsStart++; +} +if(dojo.lang.isString(_e2)){ +_e2=_e4[_e2]; +} +var _e5=[]; +for(var i=argsStart;i=4){ +this.changeUrl=_f7; +} +} +}; +dojo.lang.extend(dojo.io.Request,{url:"",mimetype:"text/plain",method:"GET",content:undefined,transport:undefined,changeUrl:undefined,formNode:undefined,sync:false,bindSuccess:false,useCache:false,preventCache:false,load:function(_f8,_f9,evt){ +},error:function(_fb,_fc){ +},timeout:function(_fd){ +},handle:function(){ +},timeoutSeconds:0,abort:function(){ +},fromKwArgs:function(_fe){ +if(_fe["url"]){ +_fe.url=_fe.url.toString(); +} +if(_fe["formNode"]){ +_fe.formNode=dojo.byId(_fe.formNode); +} +if(!_fe["method"]&&_fe["formNode"]&&_fe["formNode"].method){ +_fe.method=_fe["formNode"].method; +} +if(!_fe["handle"]&&_fe["handler"]){ +_fe.handle=_fe.handler; +} +if(!_fe["load"]&&_fe["loaded"]){ +_fe.load=_fe.loaded; +} +if(!_fe["changeUrl"]&&_fe["changeURL"]){ +_fe.changeUrl=_fe.changeURL; +} +_fe.encoding=dojo.lang.firstValued(_fe["encoding"],djConfig["bindEncoding"],""); +_fe.sendTransport=dojo.lang.firstValued(_fe["sendTransport"],djConfig["ioSendTransport"],false); +var _ff=dojo.lang.isFunction; +for(var x=0;x0){ +dojo.io.bind(dojo.io._bindQueue.shift()); +}else{ +dojo.io._queueBindInFlight=false; +} +} +}; +dojo.io._bindQueue=[]; +dojo.io._queueBindInFlight=false; +dojo.io.argsFromMap=function(map,_110,last){ +var enc=/utf/i.test(_110||"")?encodeURIComponent:dojo.string.encodeAscii; +var _113=[]; +var _114=new Object(); +for(var name in map){ +var _116=function(elt){ +var val=enc(name)+"="+enc(elt); +_113[(last==name)?"push":"unshift"](val); +}; +if(!_114[name]){ +var _119=map[name]; +if(dojo.lang.isArray(_119)){ +dojo.lang.forEach(_119,_116); +}else{ +_116(_119); +} +} +} +return _113.join("&"); +}; +dojo.io.setIFrameSrc=function(_11a,src,_11c){ +try{ +var r=dojo.render.html; +if(!_11c){ +if(r.safari){ +_11a.location=src; +}else{ +frames[_11a.name].location=src; +} +}else{ +var idoc; +if(r.ie){ +idoc=_11a.contentWindow.document; +}else{ +if(r.safari){ +idoc=_11a.document; +}else{ +idoc=_11a.contentWindow; +} +} +if(!idoc){ +_11a.location=src; +return; +}else{ +idoc.location.replace(src); +} +} +} +catch(e){ +dojo.debug(e); +dojo.debug("setIFrameSrc: "+e); +} +}; +dojo.provide("dojo.lang.array"); +dojo.require("dojo.lang.common"); +dojo.lang.has=function(obj,name){ +try{ +return (typeof obj[name]!="undefined"); +} +catch(e){ +return false; +} +}; +dojo.lang.isEmpty=function(obj){ +if(dojo.lang.isObject(obj)){ +var tmp={}; +var _123=0; +for(var x in obj){ +if(obj[x]&&(!tmp[x])){ +_123++; +break; +} +} +return (_123==0); +}else{ +if(dojo.lang.isArrayLike(obj)||dojo.lang.isString(obj)){ +return obj.length==0; +} +} +}; +dojo.lang.map=function(arr,obj,_127){ +var _128=dojo.lang.isString(arr); +if(_128){ +arr=arr.split(""); +} +if(dojo.lang.isFunction(obj)&&(!_127)){ +_127=obj; +obj=dj_global; +}else{ +if(dojo.lang.isFunction(obj)&&_127){ +var _129=obj; +obj=_127; +_127=_129; +} +} +if(Array.map){ +var _12a=Array.map(arr,_127,obj); +}else{ +var _12a=[]; +for(var i=0;i=3){ +dojo.raise("thisObject doesn't exist!"); +} +_13e=dj_global; +} +var _140=[]; +for(var i=0;i/gm,">").replace(/"/gm,"""); +if(!_183){ +str=str.replace(/'/gm,"'"); +} +return str; +}; +dojo.string.escapeSql=function(str){ +return str.replace(/'/gm,"''"); +}; +dojo.string.escapeRegExp=function(str){ +return str.replace(/\\/gm,"\\\\").replace(/([\f\b\n\t\r[\^$|?*+(){}])/gm,"\\$1"); +}; +dojo.string.escapeJavaScript=function(str){ +return str.replace(/(["'\f\b\n\t\r])/gm,"\\$1"); +}; +dojo.string.escapeString=function(str){ +return ("\""+str.replace(/(["\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r"); +}; +dojo.string.summary=function(str,len){ +if(!len||str.length<=len){ +return str; +}else{ +return str.substring(0,len).replace(/\.+$/,"")+"..."; +} +}; +dojo.string.endsWith=function(str,end,_18c){ +if(_18c){ +str=str.toLowerCase(); +end=end.toLowerCase(); +} +if((str.length-end.length)<0){ +return false; +} +return str.lastIndexOf(end)==str.length-end.length; +}; +dojo.string.endsWithAny=function(str){ +for(var i=1;i-1){ +return true; +} +} +return false; +}; +dojo.string.normalizeNewlines=function(text,_197){ +if(_197=="\n"){ +text=text.replace(/\r\n/g,"\n"); +text=text.replace(/\r/g,"\n"); +}else{ +if(_197=="\r"){ +text=text.replace(/\r\n/g,"\r"); +text=text.replace(/\n/g,"\r"); +}else{ +text=text.replace(/([^\r])\n/g,"$1\r\n"); +text=text.replace(/\r([^\n])/g,"\r\n$1"); +} +} +return text; +}; +dojo.string.splitEscaped=function(str,_199){ +var _19a=[]; +for(var i=0,prevcomma=0;i5)&&(_1a1[x].indexOf("dojo-")>=0)){ +return "dojo:"+_1a1[x].substr(5).toLowerCase(); +} +} +} +} +} +return _19e.toLowerCase(); +}; +dojo.dom.getUniqueId=function(){ +do{ +var id="dj_unique_"+(++arguments.callee._idIncrement); +}while(document.getElementById(id)); +return id; +}; +dojo.dom.getUniqueId._idIncrement=0; +dojo.dom.firstElement=dojo.dom.getFirstChildElement=function(_1a4,_1a5){ +var node=_1a4.firstChild; +while(node&&node.nodeType!=dojo.dom.ELEMENT_NODE){ +node=node.nextSibling; +} +if(_1a5&&node&&node.tagName&&node.tagName.toLowerCase()!=_1a5.toLowerCase()){ +node=dojo.dom.nextElement(node,_1a5); +} +return node; +}; +dojo.dom.lastElement=dojo.dom.getLastChildElement=function(_1a7,_1a8){ +var node=_1a7.lastChild; +while(node&&node.nodeType!=dojo.dom.ELEMENT_NODE){ +node=node.previousSibling; +} +if(_1a8&&node&&node.tagName&&node.tagName.toLowerCase()!=_1a8.toLowerCase()){ +node=dojo.dom.prevElement(node,_1a8); +} +return node; +}; +dojo.dom.nextElement=dojo.dom.getNextSiblingElement=function(node,_1ab){ +if(!node){ +return null; +} +do{ +node=node.nextSibling; +}while(node&&node.nodeType!=dojo.dom.ELEMENT_NODE); +if(node&&_1ab&&_1ab.toLowerCase()!=node.tagName.toLowerCase()){ +return dojo.dom.nextElement(node,_1ab); +} +return node; +}; +dojo.dom.prevElement=dojo.dom.getPreviousSiblingElement=function(node,_1ad){ +if(!node){ +return null; +} +if(_1ad){ +_1ad=_1ad.toLowerCase(); +} +do{ +node=node.previousSibling; +}while(node&&node.nodeType!=dojo.dom.ELEMENT_NODE); +if(node&&_1ad&&_1ad.toLowerCase()!=node.tagName.toLowerCase()){ +return dojo.dom.prevElement(node,_1ad); +} +return node; +}; +dojo.dom.moveChildren=function(_1ae,_1af,trim){ +var _1b1=0; +if(trim){ +while(_1ae.hasChildNodes()&&_1ae.firstChild.nodeType==dojo.dom.TEXT_NODE){ +_1ae.removeChild(_1ae.firstChild); +} +while(_1ae.hasChildNodes()&&_1ae.lastChild.nodeType==dojo.dom.TEXT_NODE){ +_1ae.removeChild(_1ae.lastChild); +} +} +while(_1ae.hasChildNodes()){ +_1af.appendChild(_1ae.firstChild); +_1b1++; +} +return _1b1; +}; +dojo.dom.copyChildren=function(_1b2,_1b3,trim){ +var _1b5=_1b2.cloneNode(true); +return this.moveChildren(_1b5,_1b3,trim); +}; +dojo.dom.removeChildren=function(node){ +var _1b7=node.childNodes.length; +while(node.hasChildNodes()){ +node.removeChild(node.firstChild); +} +return _1b7; +}; +dojo.dom.replaceChildren=function(node,_1b9){ +dojo.dom.removeChildren(node); +node.appendChild(_1b9); +}; +dojo.dom.removeNode=function(node){ +if(node&&node.parentNode){ +return node.parentNode.removeChild(node); +} +}; +dojo.dom.getAncestors=function(node,_1bc,_1bd){ +var _1be=[]; +var _1bf=dojo.lang.isFunction(_1bc); +while(node){ +if(!_1bf||_1bc(node)){ +_1be.push(node); +} +if(_1bd&&_1be.length>0){ +return _1be[0]; +} +node=node.parentNode; +} +if(_1bd){ +return null; +} +return _1be; +}; +dojo.dom.getAncestorsByTag=function(node,tag,_1c2){ +tag=tag.toLowerCase(); +return dojo.dom.getAncestors(node,function(el){ +return ((el.tagName)&&(el.tagName.toLowerCase()==tag)); +},_1c2); +}; +dojo.dom.getFirstAncestorByTag=function(node,tag){ +return dojo.dom.getAncestorsByTag(node,tag,true); +}; +dojo.dom.isDescendantOf=function(node,_1c7,_1c8){ +if(_1c8&&node){ +node=node.parentNode; +} +while(node){ +if(node==_1c7){ +return true; +} +node=node.parentNode; +} +return false; +}; +dojo.dom.innerXML=function(node){ +if(node.innerXML){ +return node.innerXML; +}else{ +if(node.xml){ +return node.xml; +}else{ +if(typeof XMLSerializer!="undefined"){ +return (new XMLSerializer()).serializeToString(node); +} +} +} +}; +dojo.dom.createDocument=function(){ +var doc=null; +if(!dj_undef("ActiveXObject")){ +var _1cb=["MSXML2","Microsoft","MSXML","MSXML3"]; +for(var i=0;i<_1cb.length;i++){ +try{ +doc=new ActiveXObject(_1cb[i]+".XMLDOM"); +} +catch(e){ +} +if(doc){ +break; +} +} +}else{ +if((document.implementation)&&(document.implementation.createDocument)){ +doc=document.implementation.createDocument("","",null); +} +} +return doc; +}; +dojo.dom.createDocumentFromText=function(str,_1ce){ +if(!_1ce){ +_1ce="text/xml"; +} +if(!dj_undef("DOMParser")){ +var _1cf=new DOMParser(); +return _1cf.parseFromString(str,_1ce); +}else{ +if(!dj_undef("ActiveXObject")){ +var _1d0=dojo.dom.createDocument(); +if(_1d0){ +_1d0.async=false; +_1d0.loadXML(str); +return _1d0; +}else{ +dojo.debug("toXml didn't work?"); +} +}else{ +if(document.createElement){ +var tmp=document.createElement("xml"); +tmp.innerHTML=str; +if(document.implementation&&document.implementation.createDocument){ +var _1d2=document.implementation.createDocument("foo","",null); +for(var i=0;i"); +} +} +catch(e){ +} +if(dojo.render.html.opera){ +dojo.debug("Opera is not supported with dojo.undo.browser, so back/forward detection will not work."); +} +dojo.undo.browser={initialHref:window.location.href,initialHash:window.location.hash,moveForward:false,historyStack:[],forwardStack:[],historyIframe:null,bookmarkAnchor:null,locationTimer:null,setInitialState:function(args){ +this.initialState={"url":this.initialHref,"kwArgs":args,"urlHash":this.initialHash}; +},addToHistory:function(args){ +var hash=null; +if(!this.historyIframe){ +this.historyIframe=window.frames["djhistory"]; +} +if(!this.bookmarkAnchor){ +this.bookmarkAnchor=document.createElement("a"); +(document.body||document.getElementsByTagName("body")[0]).appendChild(this.bookmarkAnchor); +this.bookmarkAnchor.style.display="none"; +} +if((!args["changeUrl"])||(dojo.render.html.ie)){ +var url=dojo.hostenv.getBaseScriptUri()+"iframe_history.html?"+(new Date()).getTime(); +this.moveForward=true; +dojo.io.setIFrameSrc(this.historyIframe,url,false); +} +if(args["changeUrl"]){ +this.changingUrl=true; +hash="#"+((args["changeUrl"]!==true)?args["changeUrl"]:(new Date()).getTime()); +setTimeout("window.location.href = '"+hash+"'; dojo.undo.browser.changingUrl = false;",1); +this.bookmarkAnchor.href=hash; +if(dojo.render.html.ie){ +var _1f4=args["back"]||args["backButton"]||args["handle"]; +var tcb=function(_1f6){ +if(window.location.hash!=""){ +setTimeout("window.location.href = '"+hash+"';",1); +} +_1f4.apply(this,[_1f6]); +}; +if(args["back"]){ +args.back=tcb; +}else{ +if(args["backButton"]){ +args.backButton=tcb; +}else{ +if(args["handle"]){ +args.handle=tcb; +} +} +} +this.forwardStack=[]; +var _1f7=args["forward"]||args["forwardButton"]||args["handle"]; +var tfw=function(_1f9){ +if(window.location.hash!=""){ +window.location.href=hash; +} +if(_1f7){ +_1f7.apply(this,[_1f9]); +} +}; +if(args["forward"]){ +args.forward=tfw; +}else{ +if(args["forwardButton"]){ +args.forwardButton=tfw; +}else{ +if(args["handle"]){ +args.handle=tfw; +} +} +} +}else{ +if(dojo.render.html.moz){ +if(!this.locationTimer){ +this.locationTimer=setInterval("dojo.undo.browser.checkLocation();",200); +} +} +} +} +this.historyStack.push({"url":url,"kwArgs":args,"urlHash":hash}); +},checkLocation:function(){ +if(!this.changingUrl){ +var hsl=this.historyStack.length; +if((window.location.hash==this.initialHash||window.location.href==this.initialHref)&&(hsl==1)){ +this.handleBackButton(); +return; +} +if(this.forwardStack.length>0){ +if(this.forwardStack[this.forwardStack.length-1].urlHash==window.location.hash){ +this.handleForwardButton(); +return; +} +} +if((hsl>=2)&&(this.historyStack[hsl-2])){ +if(this.historyStack[hsl-2].urlHash==window.location.hash){ +this.handleBackButton(); +return; +} +} +} +},iframeLoaded:function(evt,_1fc){ +if(!dojo.render.html.opera){ +var _1fd=this._getUrlQuery(_1fc.href); +if(_1fd==null){ +if(this.historyStack.length==1){ +this.handleBackButton(); +} +return; +} +if(this.moveForward){ +this.moveForward=false; +return; +} +if(this.historyStack.length>=2&&_1fd==this._getUrlQuery(this.historyStack[this.historyStack.length-2].url)){ +this.handleBackButton(); +}else{ +if(this.forwardStack.length>0&&_1fd==this._getUrlQuery(this.forwardStack[this.forwardStack.length-1].url)){ +this.handleForwardButton(); +} +} +} +},handleBackButton:function(){ +var _1fe=this.historyStack.pop(); +if(!_1fe){ +return; +} +var last=this.historyStack[this.historyStack.length-1]; +if(!last&&this.historyStack.length==0){ +last=this.initialState; +} +if(last){ +if(last.kwArgs["back"]){ +last.kwArgs["back"](); +}else{ +if(last.kwArgs["backButton"]){ +last.kwArgs["backButton"](); +}else{ +if(last.kwArgs["handle"]){ +last.kwArgs.handle("back"); +} +} +} +} +this.forwardStack.push(_1fe); +},handleForwardButton:function(){ +var last=this.forwardStack.pop(); +if(!last){ +return; +} +if(last.kwArgs["forward"]){ +last.kwArgs.forward(); +}else{ +if(last.kwArgs["forwardButton"]){ +last.kwArgs.forwardButton(); +}else{ +if(last.kwArgs["handle"]){ +last.kwArgs.handle("forward"); +} +} +} +this.historyStack.push(last); +},_getUrlQuery:function(url){ +var _202=url.split("?"); +if(_202.length<2){ +return null; +}else{ +return _202[1]; +} +}}; +dojo.provide("dojo.io.BrowserIO"); +dojo.require("dojo.io"); +dojo.require("dojo.lang.array"); +dojo.require("dojo.lang.func"); +dojo.require("dojo.string.extras"); +dojo.require("dojo.dom"); +dojo.require("dojo.undo.browser"); +dojo.io.checkChildrenForFile=function(node){ +var _204=false; +var _205=node.getElementsByTagName("input"); +dojo.lang.forEach(_205,function(_206){ +if(_204){ +return; +} +if(_206.getAttribute("type")=="file"){ +_204=true; +} +}); +return _204; +}; +dojo.io.formHasFile=function(_207){ +return dojo.io.checkChildrenForFile(_207); +}; +dojo.io.updateNode=function(node,_209){ +node=dojo.byId(node); +var args=_209; +if(dojo.lang.isString(_209)){ +args={url:_209}; +} +args.mimetype="text/html"; +args.load=function(t,d,e){ +while(node.firstChild){ +if(dojo["event"]){ +try{ +dojo.event.browser.clean(node.firstChild); +} +catch(e){ +} +} +node.removeChild(node.firstChild); +} +node.innerHTML=d; +}; +dojo.io.bind(args); +}; +dojo.io.formFilter=function(node){ +var type=(node.type||"").toLowerCase(); +return !node.disabled&&node.name&&!dojo.lang.inArray(type,["file","submit","image","reset","button"]); +}; +dojo.io.encodeForm=function(_210,_211,_212){ +if((!_210)||(!_210.tagName)||(!_210.tagName.toLowerCase()=="form")){ +dojo.raise("Attempted to encode a non-form element."); +} +if(!_212){ +_212=dojo.io.formFilter; +} +var enc=/utf/i.test(_211||"")?encodeURIComponent:dojo.string.encodeAscii; +var _214=[]; +for(var i=0;i<_210.elements.length;i++){ +var elm=_210.elements[i]; +if(!elm||elm.tagName.toLowerCase()=="fieldset"||!_212(elm)){ +continue; +} +var name=enc(elm.name); +var type=elm.type.toLowerCase(); +if(type=="select-multiple"){ +for(var j=0;j=200)&&(http.status<300))||(http.status==304)||(location.protocol=="file:"&&(http.status==0||http.status==undefined))||(location.protocol=="chrome:"&&(http.status==0||http.status==undefined))){ +var ret; +if(_23b.method.toLowerCase()=="head"){ +var _241=http.getAllResponseHeaders(); +ret={}; +ret.toString=function(){ +return _241; +}; +var _242=_241.split(/[\r\n]+/g); +for(var i=0;i<_242.length;i++){ +var pair=_242[i].match(/^([^:]+)\s*:\s*(.+)$/i); +if(pair){ +ret[pair[1]]=pair[2]; +} +} +}else{ +if(_23b.mimetype=="text/javascript"){ +try{ +ret=dj_eval(http.responseText); +} +catch(e){ +dojo.debug(e); +dojo.debug(http.responseText); +ret=null; +} +}else{ +if(_23b.mimetype=="text/json"){ +try{ +ret=dj_eval("("+http.responseText+")"); +} +catch(e){ +dojo.debug(e); +dojo.debug(http.responseText); +ret=false; +} +}else{ +if((_23b.mimetype=="application/xml")||(_23b.mimetype=="text/xml")){ +ret=http.responseXML; +if(!ret||typeof ret=="string"||!http.getResponseHeader("Content-Type")){ +ret=dojo.dom.createDocumentFromText(http.responseText); +} +}else{ +ret=http.responseText; +} +} +} +} +if(_23f){ +addToCache(url,_23e,_23b.method,http); +} +_23b[(typeof _23b.load=="function")?"load":"handle"]("load",ret,http,_23b); +}else{ +var _245=new dojo.io.Error("XMLHttpTransport Error: "+http.status+" "+http.statusText); +_23b[(typeof _23b.error=="function")?"error":"handle"]("error",_245,http,_23b); +} +} +function setHeaders(http,_247){ +if(_247["headers"]){ +for(var _248 in _247["headers"]){ +if(_248.toLowerCase()=="content-type"&&!_247["contentType"]){ +_247["contentType"]=_247["headers"][_248]; +}else{ +http.setRequestHeader(_248,_247["headers"][_248]); +} +} +} +} +this.inFlight=[]; +this.inFlightTimer=null; +this.startWatchingInFlight=function(){ +if(!this.inFlightTimer){ +this.inFlightTimer=setInterval("dojo.io.XMLHTTPTransport.watchInFlight();",10); +} +}; +this.watchInFlight=function(){ +var now=null; +for(var x=this.inFlight.length-1;x>=0;x--){ +var tif=this.inFlight[x]; +if(!tif){ +this.inFlight.splice(x,1); +continue; +} +if(4==tif.http.readyState){ +this.inFlight.splice(x,1); +doLoad(tif.req,tif.http,tif.url,tif.query,tif.useCache); +}else{ +if(tif.startTime){ +if(!now){ +now=(new Date()).getTime(); +} +if(tif.startTime+(tif.req.timeoutSeconds*1000)-1){ +dojo.debug("Warning: dojo.io.bind: stripping hash values from url:",url); +url=url.split("#")[0]; +} +if(_24e["file"]){ +_24e.method="post"; +} +if(!_24e["method"]){ +_24e.method="get"; +} +if(_24e.method.toLowerCase()=="get"){ +_24e.multipart=false; +}else{ +if(_24e["file"]){ +_24e.multipart=true; +}else{ +if(!_24e["multipart"]){ +_24e.multipart=false; +} +} +} +if(_24e["backButton"]||_24e["back"]||_24e["changeUrl"]){ +dojo.undo.browser.addToHistory(_24e); +} +var _253=_24e["content"]||{}; +if(_24e.sendTransport){ +_253["dojo.transport"]="xmlhttp"; +} +do{ +if(_24e.postContent){ +_250=_24e.postContent; +break; +} +if(_253){ +_250+=dojo.io.argsFromMap(_253,_24e.encoding); +} +if(_24e.method.toLowerCase()=="get"||!_24e.multipart){ +break; +} +var t=[]; +if(_250.length){ +var q=_250.split("&"); +for(var i=0;i-1?"&":"?")+_250; +} +if(_25a){ +_260+=(dojo.string.endsWithAny(_260,"?","&")?"":(_260.indexOf("?")>-1?"&":"?"))+"dojo.preventCache="+new Date().valueOf(); +} +http.open(_24e.method.toUpperCase(),_260,_259); +setHeaders(http,_24e); +try{ +http.send(null); +} +catch(e){ +if(typeof http.abort=="function"){ +http.abort(); +} +doLoad(_24e,{status:404},url,_250,_25b); +} +} +if(!_259){ +doLoad(_24e,http,url,_250,_25b); +} +_24e.abort=function(){ +return http.abort(); +}; +return; +}; +dojo.io.transports.addTransport("XMLHTTPTransport"); +}; +dojo.provide("dojo.event"); +dojo.require("dojo.lang.array"); +dojo.require("dojo.lang.extras"); +dojo.require("dojo.lang.func"); +dojo.event=new function(){ +this.canTimeout=dojo.lang.isFunction(dj_global["setTimeout"])||dojo.lang.isAlien(dj_global["setTimeout"]); +function interpolateArgs(args,_262){ +var dl=dojo.lang; +var ao={srcObj:dj_global,srcFunc:null,adviceObj:dj_global,adviceFunc:null,aroundObj:null,aroundFunc:null,adviceType:(args.length>2)?args[0]:"after",precedence:"last",once:false,delay:null,rate:0,adviceMsg:false}; +switch(args.length){ +case 0: +return; +case 1: +return; +case 2: +ao.srcFunc=args[0]; +ao.adviceFunc=args[1]; +break; +case 3: +if((dl.isObject(args[0]))&&(dl.isString(args[1]))&&(dl.isString(args[2]))){ +ao.adviceType="after"; +ao.srcObj=args[0]; +ao.srcFunc=args[1]; +ao.adviceFunc=args[2]; +}else{ +if((dl.isString(args[1]))&&(dl.isString(args[2]))){ +ao.srcFunc=args[1]; +ao.adviceFunc=args[2]; +}else{ +if((dl.isObject(args[0]))&&(dl.isString(args[1]))&&(dl.isFunction(args[2]))){ +ao.adviceType="after"; +ao.srcObj=args[0]; +ao.srcFunc=args[1]; +var _265=dl.nameAnonFunc(args[2],ao.adviceObj,_262); +ao.adviceFunc=_265; +}else{ +if((dl.isFunction(args[0]))&&(dl.isObject(args[1]))&&(dl.isString(args[2]))){ +ao.adviceType="after"; +ao.srcObj=dj_global; +var _265=dl.nameAnonFunc(args[0],ao.srcObj,_262); +ao.srcFunc=_265; +ao.adviceObj=args[1]; +ao.adviceFunc=args[2]; +} +} +} +} +break; +case 4: +if((dl.isObject(args[0]))&&(dl.isObject(args[2]))){ +ao.adviceType="after"; +ao.srcObj=args[0]; +ao.srcFunc=args[1]; +ao.adviceObj=args[2]; +ao.adviceFunc=args[3]; +}else{ +if((dl.isString(args[0]))&&(dl.isString(args[1]))&&(dl.isObject(args[2]))){ +ao.adviceType=args[0]; +ao.srcObj=dj_global; +ao.srcFunc=args[1]; +ao.adviceObj=args[2]; +ao.adviceFunc=args[3]; +}else{ +if((dl.isString(args[0]))&&(dl.isFunction(args[1]))&&(dl.isObject(args[2]))){ +ao.adviceType=args[0]; +ao.srcObj=dj_global; +var _265=dl.nameAnonFunc(args[1],dj_global,_262); +ao.srcFunc=_265; +ao.adviceObj=args[2]; +ao.adviceFunc=args[3]; +}else{ +if((dl.isString(args[0]))&&(dl.isObject(args[1]))&&(dl.isString(args[2]))&&(dl.isFunction(args[3]))){ +ao.srcObj=args[1]; +ao.srcFunc=args[2]; +var _265=dl.nameAnonFunc(args[3],dj_global,_262); +ao.adviceObj=dj_global; +ao.adviceFunc=_265; +}else{ +if(dl.isObject(args[1])){ +ao.srcObj=args[1]; +ao.srcFunc=args[2]; +ao.adviceObj=dj_global; +ao.adviceFunc=args[3]; +}else{ +if(dl.isObject(args[2])){ +ao.srcObj=dj_global; +ao.srcFunc=args[1]; +ao.adviceObj=args[2]; +ao.adviceFunc=args[3]; +}else{ +ao.srcObj=ao.adviceObj=ao.aroundObj=dj_global; +ao.srcFunc=args[1]; +ao.adviceFunc=args[2]; +ao.aroundFunc=args[3]; +} +} +} +} +} +} +break; +case 6: +ao.srcObj=args[1]; +ao.srcFunc=args[2]; +ao.adviceObj=args[3]; +ao.adviceFunc=args[4]; +ao.aroundFunc=args[5]; +ao.aroundObj=dj_global; +break; +default: +ao.srcObj=args[1]; +ao.srcFunc=args[2]; +ao.adviceObj=args[3]; +ao.adviceFunc=args[4]; +ao.aroundObj=args[5]; +ao.aroundFunc=args[6]; +ao.once=args[7]; +ao.delay=args[8]; +ao.rate=args[9]; +ao.adviceMsg=args[10]; +break; +} +if(dl.isFunction(ao.aroundFunc)){ +var _265=dl.nameAnonFunc(ao.aroundFunc,ao.aroundObj,_262); +ao.aroundFunc=_265; +} +if(dl.isFunction(ao.srcFunc)){ +ao.srcFunc=dl.getNameInObj(ao.srcObj,ao.srcFunc); +} +if(dl.isFunction(ao.adviceFunc)){ +ao.adviceFunc=dl.getNameInObj(ao.adviceObj,ao.adviceFunc); +} +if((ao.aroundObj)&&(dl.isFunction(ao.aroundFunc))){ +ao.aroundFunc=dl.getNameInObj(ao.aroundObj,ao.aroundFunc); +} +if(!ao.srcObj){ +dojo.raise("bad srcObj for srcFunc: "+ao.srcFunc); +} +if(!ao.adviceObj){ +dojo.raise("bad adviceObj for adviceFunc: "+ao.adviceFunc); +} +return ao; +} +this.connect=function(){ +if(arguments.length==1){ +var ao=arguments[0]; +}else{ +var ao=interpolateArgs(arguments,true); +} +if(dojo.lang.isArray(ao.srcObj)&&ao.srcObj!=""){ +var _267={}; +for(var x in ao){ +_267[x]=ao[x]; +} +var mjps=[]; +dojo.lang.forEach(ao.srcObj,function(src){ +if((dojo.render.html.capable)&&(dojo.lang.isString(src))){ +src=dojo.byId(src); +} +_267.srcObj=src; +mjps.push(dojo.event.connect.call(dojo.event,_267)); +}); +return mjps; +} +var mjp=dojo.event.MethodJoinPoint.getForMethod(ao.srcObj,ao.srcFunc); +if(ao.adviceFunc){ +var mjp2=dojo.event.MethodJoinPoint.getForMethod(ao.adviceObj,ao.adviceFunc); +} +mjp.kwAddAdvice(ao); +return mjp; +}; +this.log=function(a1,a2){ +var _26f; +if((arguments.length==1)&&(typeof a1=="object")){ +_26f=a1; +}else{ +_26f={srcObj:a1,srcFunc:a2}; +} +_26f.adviceFunc=function(){ +var _270=[]; +for(var x=0;x=this.jp_.around.length){ +return this.jp_.object[this.jp_.methodname].apply(this.jp_.object,this.args); +}else{ +var ti=this.jp_.around[this.around_index]; +var mobj=ti[0]||dj_global; +var meth=ti[1]; +return mobj[meth].call(mobj,this); +} +}; +dojo.event.MethodJoinPoint=function(obj,_287){ +this.object=obj||dj_global; +this.methodname=_287; +this.methodfunc=this.object[_287]; +this.before=[]; +this.after=[]; +this.around=[]; +}; +dojo.event.MethodJoinPoint.getForMethod=function(obj,_289){ +if(!obj){ +obj=dj_global; +} +if(!obj[_289]){ +obj[_289]=function(){ +}; +if(!obj[_289]){ +dojo.raise("Cannot set do-nothing method on that object "+_289); +} +}else{ +if((!dojo.lang.isFunction(obj[_289]))&&(!dojo.lang.isAlien(obj[_289]))){ +return null; +} +} +var _28a=_289+"$joinpoint"; +var _28b=_289+"$joinpoint$method"; +var _28c=obj[_28a]; +if(!_28c){ +var _28d=false; +if(dojo.event["browser"]){ +if((obj["attachEvent"])||(obj["nodeType"])||(obj["addEventListener"])){ +_28d=true; +dojo.event.browser.addClobberNodeAttrs(obj,[_28a,_28b,_289]); +} +} +var _28e=obj[_289].length; +obj[_28b]=obj[_289]; +_28c=obj[_28a]=new dojo.event.MethodJoinPoint(obj,_28b); +obj[_289]=function(){ +var args=[]; +if((_28d)&&(!arguments.length)){ +var evt=null; +try{ +if(obj.ownerDocument){ +evt=obj.ownerDocument.parentWindow.event; +}else{ +if(obj.documentElement){ +evt=obj.documentElement.ownerDocument.parentWindow.event; +}else{ +evt=window.event; +} +} +} +catch(e){ +evt=window.event; +} +if(evt){ +args.push(dojo.event.browser.fixEvent(evt,this)); +} +}else{ +for(var x=0;x0){ +dojo.lang.forEach(this.before,_296); +} +var _2a6; +if(this.around.length>0){ +var mi=new dojo.event.MethodInvocation(this,obj,args); +_2a6=mi.proceed(); +}else{ +if(this.methodfunc){ +_2a6=this.object[this.methodname].apply(this.object,args); +} +} +if(this.after.length>0){ +dojo.lang.forEach(this.after,_296); +} +return (this.methodfunc)?_2a6:null; +},getArr:function(kind){ +var arr=this.after; +if((typeof kind=="string")&&(kind.indexOf("before")!=-1)){ +arr=this.before; +}else{ +if(kind=="around"){ +arr=this.around; +} +} +return arr; +},kwAddAdvice:function(args){ +this.addAdvice(args["adviceObj"],args["adviceFunc"],args["aroundObj"],args["aroundFunc"],args["adviceType"],args["precedence"],args["once"],args["delay"],args["rate"],args["adviceMsg"]); +},addAdvice:function(_2ab,_2ac,_2ad,_2ae,_2af,_2b0,once,_2b2,rate,_2b4){ +var arr=this.getArr(_2af); +if(!arr){ +dojo.raise("bad this: "+this); +} +var ao=[_2ab,_2ac,_2ad,_2ae,_2b2,rate,_2b4]; +if(once){ +if(this.hasAdvice(_2ab,_2ac,_2af,arr)>=0){ +return; +} +} +if(_2b0=="first"){ +arr.unshift(ao); +}else{ +arr.push(ao); +} +},hasAdvice:function(_2b7,_2b8,_2b9,arr){ +if(!arr){ +arr=this.getArr(_2b9); +} +var ind=-1; +for(var x=0;x=0;i=i-1){ +var el=na[i]; +if(el["__clobberAttrs__"]){ +for(var j=0;j0){ +this.duration=_319; +} +if(_31c){ +this.repeatCount=_31c; +} +if(rate){ +this.rate=rate; +} +if(_318){ +this.handler=_318.handler; +this.beforeBegin=_318.beforeBegin; +this.onBegin=_318.onBegin; +this.onEnd=_318.onEnd; +this.onPlay=_318.onPlay; +this.onPause=_318.onPause; +this.onStop=_318.onStop; +this.onAnimate=_318.onAnimate; +} +if(_31b&&dojo.lang.isFunction(_31b)){ +this.easing=_31b; +} +}; +dojo.inherits(dojo.lfx.Animation,dojo.lfx.IAnimation); +dojo.lang.extend(dojo.lfx.Animation,{_startTime:null,_endTime:null,_timer:null,_percent:0,_startRepeatCount:0,play:function(_31e,_31f){ +if(_31f){ +clearTimeout(this._timer); +this._active=false; +this._paused=false; +this._percent=0; +}else{ +if(this._active&&!this._paused){ +return this; +} +} +this.fire("handler",["beforeBegin"]); +this.fire("beforeBegin"); +if(_31e>0){ +setTimeout(dojo.lang.hitch(this,function(){ +this.play(null,_31f); +}),_31e); +return this; +} +this._startTime=new Date().valueOf(); +if(this._paused){ +this._startTime-=(this.duration*this._percent/100); +} +this._endTime=this._startTime+this.duration; +this._active=true; +this._paused=false; +var step=this._percent/100; +var _321=this.curve.getValue(step); +if(this._percent==0){ +if(!this._startRepeatCount){ +this._startRepeatCount=this.repeatCount; +} +this.fire("handler",["begin",_321]); +this.fire("onBegin",[_321]); +} +this.fire("handler",["play",_321]); +this.fire("onPlay",[_321]); +this._cycle(); +return this; +},pause:function(){ +clearTimeout(this._timer); +if(!this._active){ +return this; +} +this._paused=true; +var _322=this.curve.getValue(this._percent/100); +this.fire("handler",["pause",_322]); +this.fire("onPause",[_322]); +return this; +},gotoPercent:function(pct,_324){ +clearTimeout(this._timer); +this._active=true; +this._paused=true; +this._percent=pct; +if(_324){ +this.play(); +} +},stop:function(_325){ +clearTimeout(this._timer); +var step=this._percent/100; +if(_325){ +step=1; +} +var _327=this.curve.getValue(step); +this.fire("handler",["stop",_327]); +this.fire("onStop",[_327]); +this._active=false; +this._paused=false; +return this; +},status:function(){ +if(this._active){ +return this._paused?"paused":"playing"; +}else{ +return "stopped"; +} +},_cycle:function(){ +clearTimeout(this._timer); +if(this._active){ +var curr=new Date().valueOf(); +var step=(curr-this._startTime)/(this._endTime-this._startTime); +if(step>=1){ +step=1; +this._percent=100; +}else{ +this._percent=step*100; +} +if((this.easing)&&(dojo.lang.isFunction(this.easing))){ +step=this.easing(step); +} +var _32a=this.curve.getValue(step); +this.fire("handler",["animate",_32a]); +this.fire("onAnimate",[_32a]); +if(step<1){ +this._timer=setTimeout(dojo.lang.hitch(this,"_cycle"),this.rate); +}else{ +this._active=false; +this.fire("handler",["end"]); +this.fire("onEnd"); +if(this.repeatCount>0){ +this.repeatCount--; +this.play(null,true); +}else{ +if(this.repeatCount==-1){ +this.play(null,true); +}else{ +if(this._startRepeatCount){ +this.repeatCount=this._startRepeatCount; +this._startRepeatCount=0; +} +} +} +} +} +return this; +}}); +dojo.lfx.Combine=function(){ +dojo.lfx.IAnimation.call(this); +this._anims=[]; +this._animsEnded=0; +var _32b=arguments; +if(_32b.length==1&&(dojo.lang.isArray(_32b[0])||dojo.lang.isArrayLike(_32b[0]))){ +_32b=_32b[0]; +} +var _32c=this; +dojo.lang.forEach(_32b,function(anim){ +_32c._anims.push(anim); +var _32e=(anim["onEnd"])?dojo.lang.hitch(anim,"onEnd"):function(){ +}; +anim.onEnd=function(){ +_32e(); +_32c._onAnimsEnded(); +}; +}); +}; +dojo.inherits(dojo.lfx.Combine,dojo.lfx.IAnimation); +dojo.lang.extend(dojo.lfx.Combine,{_animsEnded:0,play:function(_32f,_330){ +if(!this._anims.length){ +return this; +} +this.fire("beforeBegin"); +if(_32f>0){ +setTimeout(dojo.lang.hitch(this,function(){ +this.play(null,_330); +}),_32f); +return this; +} +if(_330||this._anims[0].percent==0){ +this.fire("onBegin"); +} +this.fire("onPlay"); +this._animsCall("play",null,_330); +return this; +},pause:function(){ +this.fire("onPause"); +this._animsCall("pause"); +return this; +},stop:function(_331){ +this.fire("onStop"); +this._animsCall("stop",_331); +return this; +},_onAnimsEnded:function(){ +this._animsEnded++; +if(this._animsEnded>=this._anims.length){ +this.fire("onEnd"); +} +return this; +},_animsCall:function(_332){ +var args=[]; +if(arguments.length>1){ +for(var i=1;i0){ +setTimeout(dojo.lang.hitch(this,function(){ +this.play(null,_33e); +}),_33d); +return this; +} +if(_33f){ +if(this._currAnim==0){ +this.fire("handler",["begin",this._currAnim]); +this.fire("onBegin",[this._currAnim]); +} +this.fire("onPlay",[this._currAnim]); +_33f.play(null,_33e); +} +return this; +},pause:function(){ +if(this._anims[this._currAnim]){ +this._anims[this._currAnim].pause(); +this.fire("onPause",[this._currAnim]); +} +return this; +},playPause:function(){ +if(this._anims.length==0){ +return this; +} +if(this._currAnim==-1){ +this._currAnim=0; +} +var _340=this._anims[this._currAnim]; +if(_340){ +if(!_340._active||_340._paused){ +this.play(); +}else{ +this.pause(); +} +} +return this; +},stop:function(){ +var _341=this._anims[this._currAnim]; +if(_341){ +_341.stop(); +this.fire("onStop",[this._currAnim]); +} +return _341; +},_playNext:function(){ +if(this._currAnim==-1||this._anims.length==0){ +return this; +} +this._currAnim++; +if(this._anims[this._currAnim]){ +this._anims[this._currAnim].play(null,true); +} +return this; +}}); +dojo.lfx.combine=function(){ +var _342=arguments; +if(dojo.lang.isArray(arguments[0])){ +_342=arguments[0]; +} +return new dojo.lfx.Combine(_342); +}; +dojo.lfx.chain=function(){ +var _343=arguments; +if(dojo.lang.isArray(arguments[0])){ +_343=arguments[0]; +} +return new dojo.lfx.Chain(_343); +}; +dojo.provide("dojo.graphics.color"); +dojo.require("dojo.lang.array"); +dojo.graphics.color.Color=function(r,g,b,a){ +if(dojo.lang.isArray(r)){ +this.r=r[0]; +this.g=r[1]; +this.b=r[2]; +this.a=r[3]||1; +}else{ +if(dojo.lang.isString(r)){ +var rgb=dojo.graphics.color.extractRGB(r); +this.r=rgb[0]; +this.g=rgb[1]; +this.b=rgb[2]; +this.a=g||1; +}else{ +if(r instanceof dojo.graphics.color.Color){ +this.r=r.r; +this.b=r.b; +this.g=r.g; +this.a=r.a; +}else{ +this.r=r; +this.g=g; +this.b=b; +this.a=a; +} +} +} +}; +dojo.graphics.color.Color.fromArray=function(arr){ +return new dojo.graphics.color.Color(arr[0],arr[1],arr[2],arr[3]); +}; +dojo.lang.extend(dojo.graphics.color.Color,{toRgb:function(_34a){ +if(_34a){ +return this.toRgba(); +}else{ +return [this.r,this.g,this.b]; +} +},toRgba:function(){ +return [this.r,this.g,this.b,this.a]; +},toHex:function(){ +return dojo.graphics.color.rgb2hex(this.toRgb()); +},toCss:function(){ +return "rgb("+this.toRgb().join()+")"; +},toString:function(){ +return this.toHex(); +},blend:function(_34b,_34c){ +return dojo.graphics.color.blend(this.toRgb(),new dojo.graphics.color.Color(_34b).toRgb(),_34c); +}}); +dojo.graphics.color.named={white:[255,255,255],black:[0,0,0],red:[255,0,0],green:[0,255,0],blue:[0,0,255],navy:[0,0,128],gray:[128,128,128],silver:[192,192,192]}; +dojo.graphics.color.blend=function(a,b,_34f){ +if(typeof a=="string"){ +return dojo.graphics.color.blendHex(a,b,_34f); +} +if(!_34f){ +_34f=0; +}else{ +if(_34f>1){ +_34f=1; +}else{ +if(_34f<-1){ +_34f=-1; +} +} +} +var c=new Array(3); +for(var i=0;i<3;i++){ +var half=Math.abs(a[i]-b[i])/2; +c[i]=Math.floor(Math.min(a[i],b[i])+half+(half*_34f)); +} +return c; +}; +dojo.graphics.color.blendHex=function(a,b,_355){ +return dojo.graphics.color.rgb2hex(dojo.graphics.color.blend(dojo.graphics.color.hex2rgb(a),dojo.graphics.color.hex2rgb(b),_355)); +}; +dojo.graphics.color.extractRGB=function(_356){ +var hex="0123456789abcdef"; +_356=_356.toLowerCase(); +if(_356.indexOf("rgb")==0){ +var _358=_356.match(/rgba*\((\d+), *(\d+), *(\d+)/i); +var ret=_358.splice(1,3); +return ret; +}else{ +var _35a=dojo.graphics.color.hex2rgb(_356); +if(_35a){ +return _35a; +}else{ +return dojo.graphics.color.named[_356]||[255,255,255]; +} +} +}; +dojo.graphics.color.hex2rgb=function(hex){ +var _35c="0123456789ABCDEF"; +var rgb=new Array(3); +if(hex.indexOf("#")==0){ +hex=hex.substring(1); +} +hex=hex.toUpperCase(); +if(hex.replace(new RegExp("["+_35c+"]","g"),"")!=""){ +return null; +} +if(hex.length==3){ +rgb[0]=hex.charAt(0)+hex.charAt(0); +rgb[1]=hex.charAt(1)+hex.charAt(1); +rgb[2]=hex.charAt(2)+hex.charAt(2); +}else{ +rgb[0]=hex.substring(0,2); +rgb[1]=hex.substring(2,4); +rgb[2]=hex.substring(4); +} +for(var i=0;i0&&!(j==1&&segs[0]=="")&&segs[j]==".."&&segs[j-1]!=".."){ +if(j==segs.length-1){ +segs.splice(j,1); +segs[j-1]=""; +}else{ +segs.splice(j-1,2); +j-=2; +} +} +} +} +_36a.path=segs.join("/"); +} +} +} +} +uri=""; +if(_36a.scheme!=null){ +uri+=_36a.scheme+":"; +} +if(_36a.authority!=null){ +uri+="//"+_36a.authority; +} +uri+=_36a.path; +if(_36a.query!=null){ +uri+="?"+_36a.query; +} +if(_36a.fragment!=null){ +uri+="#"+_36a.fragment; +} +} +this.uri=uri.toString(); +var _36f="^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"; +var r=this.uri.match(new RegExp(_36f)); +this.scheme=r[2]||(r[1]?"":null); +this.authority=r[4]||(r[3]?"":null); +this.path=r[5]; +this.query=r[7]||(r[6]?"":null); +this.fragment=r[9]||(r[8]?"":null); +if(this.authority!=null){ +_36f="^((([^:]+:)?([^@]+))@)?([^:]*)(:([0-9]+))?$"; +r=this.authority.match(new RegExp(_36f)); +this.user=r[3]||null; +this.password=r[4]||null; +this.host=r[5]; +this.port=r[7]||null; +} +this.toString=function(){ +return this.uri; +}; +}; +}; +dojo.provide("dojo.style"); +dojo.require("dojo.graphics.color"); +dojo.require("dojo.uri.Uri"); +dojo.require("dojo.lang.common"); +(function(){ +var h=dojo.render.html; +var ds=dojo.style; +var db=document["body"]||document["documentElement"]; +ds.boxSizing={MARGIN_BOX:"margin-box",BORDER_BOX:"border-box",PADDING_BOX:"padding-box",CONTENT_BOX:"content-box"}; +var bs=ds.boxSizing; +ds.getBoxSizing=function(node){ +if((h.ie)||(h.opera)){ +var cm=document["compatMode"]; +if((cm=="BackCompat")||(cm=="QuirksMode")){ +return bs.BORDER_BOX; +}else{ +return bs.CONTENT_BOX; +} +}else{ +if(arguments.length==0){ +node=document.documentElement; +} +var _377=ds.getStyle(node,"-moz-box-sizing"); +if(!_377){ +_377=ds.getStyle(node,"box-sizing"); +} +return (_377?_377:bs.CONTENT_BOX); +} +}; +ds.isBorderBox=function(node){ +return (ds.getBoxSizing(node)==bs.BORDER_BOX); +}; +ds.getUnitValue=function(node,_37a,_37b){ +var s=ds.getComputedStyle(node,_37a); +if((!s)||((s=="auto")&&(_37b))){ +return {value:0,units:"px"}; +} +if(dojo.lang.isUndefined(s)){ +return ds.getUnitValue.bad; +} +var _37d=s.match(/(\-?[\d.]+)([a-z%]*)/i); +if(!_37d){ +return ds.getUnitValue.bad; +} +return {value:Number(_37d[1]),units:_37d[2].toLowerCase()}; +}; +ds.getUnitValue.bad={value:NaN,units:""}; +ds.getPixelValue=function(node,_37f,_380){ +var _381=ds.getUnitValue(node,_37f,_380); +if(isNaN(_381.value)){ +return 0; +} +if((_381.value)&&(_381.units!="px")){ +return NaN; +} +return _381.value; +}; +ds.getNumericStyle=function(){ +dojo.deprecated("dojo.(style|html).getNumericStyle","in favor of dojo.(style|html).getPixelValue","0.4"); +return ds.getPixelValue.apply(this,arguments); +}; +ds.setPositivePixelValue=function(node,_383,_384){ +if(isNaN(_384)){ +return false; +} +node.style[_383]=Math.max(0,_384)+"px"; +return true; +}; +ds._sumPixelValues=function(node,_386,_387){ +var _388=0; +for(var x=0;x<_386.length;x++){ +_388+=ds.getPixelValue(node,_386[x],_387); +} +return _388; +}; +ds.isPositionAbsolute=function(node){ +return (ds.getComputedStyle(node,"position")=="absolute"); +}; +ds.getBorderExtent=function(node,side){ +return (ds.getStyle(node,"border-"+side+"-style")=="none"?0:ds.getPixelValue(node,"border-"+side+"-width")); +}; +ds.getMarginWidth=function(node){ +return ds._sumPixelValues(node,["margin-left","margin-right"],ds.isPositionAbsolute(node)); +}; +ds.getBorderWidth=function(node){ +return ds.getBorderExtent(node,"left")+ds.getBorderExtent(node,"right"); +}; +ds.getPaddingWidth=function(node){ +return ds._sumPixelValues(node,["padding-left","padding-right"],true); +}; +ds.getPadBorderWidth=function(node){ +return ds.getPaddingWidth(node)+ds.getBorderWidth(node); +}; +ds.getContentBoxWidth=function(node){ +node=dojo.byId(node); +return node.offsetWidth-ds.getPadBorderWidth(node); +}; +ds.getBorderBoxWidth=function(node){ +node=dojo.byId(node); +return node.offsetWidth; +}; +ds.getMarginBoxWidth=function(node){ +return ds.getInnerWidth(node)+ds.getMarginWidth(node); +}; +ds.setContentBoxWidth=function(node,_395){ +node=dojo.byId(node); +if(ds.isBorderBox(node)){ +_395+=ds.getPadBorderWidth(node); +} +return ds.setPositivePixelValue(node,"width",_395); +}; +ds.setMarginBoxWidth=function(node,_397){ +node=dojo.byId(node); +if(!ds.isBorderBox(node)){ +_397-=ds.getPadBorderWidth(node); +} +_397-=ds.getMarginWidth(node); +return ds.setPositivePixelValue(node,"width",_397); +}; +ds.getContentWidth=ds.getContentBoxWidth; +ds.getInnerWidth=ds.getBorderBoxWidth; +ds.getOuterWidth=ds.getMarginBoxWidth; +ds.setContentWidth=ds.setContentBoxWidth; +ds.setOuterWidth=ds.setMarginBoxWidth; +ds.getMarginHeight=function(node){ +return ds._sumPixelValues(node,["margin-top","margin-bottom"],ds.isPositionAbsolute(node)); +}; +ds.getBorderHeight=function(node){ +return ds.getBorderExtent(node,"top")+ds.getBorderExtent(node,"bottom"); +}; +ds.getPaddingHeight=function(node){ +return ds._sumPixelValues(node,["padding-top","padding-bottom"],true); +}; +ds.getPadBorderHeight=function(node){ +return ds.getPaddingHeight(node)+ds.getBorderHeight(node); +}; +ds.getContentBoxHeight=function(node){ +node=dojo.byId(node); +return node.offsetHeight-ds.getPadBorderHeight(node); +}; +ds.getBorderBoxHeight=function(node){ +node=dojo.byId(node); +return node.offsetHeight; +}; +ds.getMarginBoxHeight=function(node){ +return ds.getInnerHeight(node)+ds.getMarginHeight(node); +}; +ds.setContentBoxHeight=function(node,_3a0){ +node=dojo.byId(node); +if(ds.isBorderBox(node)){ +_3a0+=ds.getPadBorderHeight(node); +} +return ds.setPositivePixelValue(node,"height",_3a0); +}; +ds.setMarginBoxHeight=function(node,_3a2){ +node=dojo.byId(node); +if(!ds.isBorderBox(node)){ +_3a2-=ds.getPadBorderHeight(node); +} +_3a2-=ds.getMarginHeight(node); +return ds.setPositivePixelValue(node,"height",_3a2); +}; +ds.getContentHeight=ds.getContentBoxHeight; +ds.getInnerHeight=ds.getBorderBoxHeight; +ds.getOuterHeight=ds.getMarginBoxHeight; +ds.setContentHeight=ds.setContentBoxHeight; +ds.setOuterHeight=ds.setMarginBoxHeight; +ds.getAbsolutePosition=ds.abs=function(node,_3a4){ +node=dojo.byId(node); +var ret=[]; +ret.x=ret.y=0; +var st=dojo.html.getScrollTop(); +var sl=dojo.html.getScrollLeft(); +if(h.ie){ +with(node.getBoundingClientRect()){ +ret.x=left-2; +ret.y=top-2; +} +}else{ +if(document.getBoxObjectFor){ +var bo=document.getBoxObjectFor(node); +ret.x=bo.x-ds.sumAncestorProperties(node,"scrollLeft"); +ret.y=bo.y-ds.sumAncestorProperties(node,"scrollTop"); +}else{ +if(node["offsetParent"]){ +var _3a9; +if((h.safari)&&(node.style.getPropertyValue("position")=="absolute")&&(node.parentNode==db)){ +_3a9=db; +}else{ +_3a9=db.parentNode; +} +if(node.parentNode!=db){ +var nd=node; +if(window.opera){ +nd=db; +} +ret.x-=ds.sumAncestorProperties(nd,"scrollLeft"); +ret.y-=ds.sumAncestorProperties(nd,"scrollTop"); +} +do{ +var n=node["offsetLeft"]; +ret.x+=isNaN(n)?0:n; +var m=node["offsetTop"]; +ret.y+=isNaN(m)?0:m; +node=node.offsetParent; +}while((node!=_3a9)&&(node!=null)); +}else{ +if(node["x"]&&node["y"]){ +ret.x+=isNaN(node.x)?0:node.x; +ret.y+=isNaN(node.y)?0:node.y; +} +} +} +} +if(_3a4){ +ret.y+=st; +ret.x+=sl; +} +ret[0]=ret.x; +ret[1]=ret.y; +return ret; +}; +ds.sumAncestorProperties=function(node,prop){ +node=dojo.byId(node); +if(!node){ +return 0; +} +var _3af=0; +while(node){ +var val=node[prop]; +if(val){ +_3af+=val-0; +if(node==document.body){ +break; +} +} +node=node.parentNode; +} +return _3af; +}; +ds.getTotalOffset=function(node,type,_3b3){ +return ds.abs(node,_3b3)[(type=="top")?"y":"x"]; +}; +ds.getAbsoluteX=ds.totalOffsetLeft=function(node,_3b5){ +return ds.getTotalOffset(node,"left",_3b5); +}; +ds.getAbsoluteY=ds.totalOffsetTop=function(node,_3b7){ +return ds.getTotalOffset(node,"top",_3b7); +}; +ds.styleSheet=null; +ds.insertCssRule=function(_3b8,_3b9,_3ba){ +if(!ds.styleSheet){ +if(document.createStyleSheet){ +ds.styleSheet=document.createStyleSheet(); +}else{ +if(document.styleSheets[0]){ +ds.styleSheet=document.styleSheets[0]; +}else{ +return null; +} +} +} +if(arguments.length<3){ +if(ds.styleSheet.cssRules){ +_3ba=ds.styleSheet.cssRules.length; +}else{ +if(ds.styleSheet.rules){ +_3ba=ds.styleSheet.rules.length; +}else{ +return null; +} +} +} +if(ds.styleSheet.insertRule){ +var rule=_3b8+" { "+_3b9+" }"; +return ds.styleSheet.insertRule(rule,_3ba); +}else{ +if(ds.styleSheet.addRule){ +return ds.styleSheet.addRule(_3b8,_3b9,_3ba); +}else{ +return null; +} +} +}; +ds.removeCssRule=function(_3bc){ +if(!ds.styleSheet){ +dojo.debug("no stylesheet defined for removing rules"); +return false; +} +if(h.ie){ +if(!_3bc){ +_3bc=ds.styleSheet.rules.length; +ds.styleSheet.removeRule(_3bc); +} +}else{ +if(document.styleSheets[0]){ +if(!_3bc){ +_3bc=ds.styleSheet.cssRules.length; +} +ds.styleSheet.deleteRule(_3bc); +} +} +return true; +}; +ds.insertCssFile=function(URI,doc,_3bf){ +if(!URI){ +return; +} +if(!doc){ +doc=document; +} +var _3c0=dojo.hostenv.getText(URI); +_3c0=ds.fixPathsInCssText(_3c0,URI); +if(_3bf){ +var _3c1=doc.getElementsByTagName("style"); +var _3c2=""; +for(var i=0;i<_3c1.length;i++){ +_3c2=(_3c1[i].styleSheet&&_3c1[i].styleSheet.cssText)?_3c1[i].styleSheet.cssText:_3c1[i].innerHTML; +if(_3c0==_3c2){ +return; +} +} +} +var _3c4=ds.insertCssText(_3c0); +if(_3c4&&djConfig.isDebug){ +_3c4.setAttribute("dbgHref",URI); +} +return _3c4; +}; +ds.insertCssText=function(_3c5,doc,URI){ +if(!_3c5){ +return; +} +if(!doc){ +doc=document; +} +if(URI){ +_3c5=ds.fixPathsInCssText(_3c5,URI); +} +var _3c8=doc.createElement("style"); +_3c8.setAttribute("type","text/css"); +var head=doc.getElementsByTagName("head")[0]; +if(!head){ +dojo.debug("No head tag in document, aborting styles"); +return; +}else{ +head.appendChild(_3c8); +} +if(_3c8.styleSheet){ +_3c8.styleSheet.cssText=_3c5; +}else{ +var _3ca=doc.createTextNode(_3c5); +_3c8.appendChild(_3ca); +} +return _3c8; +}; +ds.fixPathsInCssText=function(_3cb,URI){ +if(!_3cb||!URI){ +return; +} +var pos=0; +var str=""; +var url=""; +while(pos!=-1){ +pos=0; +url=""; +pos=_3cb.indexOf("url(",pos); +if(pos<0){ +break; +} +str+=_3cb.slice(0,pos+4); +_3cb=_3cb.substring(pos+4,_3cb.length); +url+=_3cb.match(/^[\t\s\w()\/.\\'"-:#=&?]*\)/)[0]; +_3cb=_3cb.substring(url.length-1,_3cb.length); +url=url.replace(/^[\s\t]*(['"]?)([\w()\/.\\'"-:#=&?]*)\1[\s\t]*?\)/,"$2"); +if(url.search(/(file|https?|ftps?):\/\//)==-1){ +url=(new dojo.uri.Uri(URI,url).toString()); +} +str+=url; +} +return str+_3cb; +}; +ds.getBackgroundColor=function(node){ +node=dojo.byId(node); +var _3d1; +do{ +_3d1=ds.getStyle(node,"background-color"); +if(_3d1.toLowerCase()=="rgba(0, 0, 0, 0)"){ +_3d1="transparent"; +} +if(node==document.getElementsByTagName("body")[0]){ +node=null; +break; +} +node=node.parentNode; +}while(node&&dojo.lang.inArray(_3d1,["transparent",""])); +if(_3d1=="transparent"){ +_3d1=[255,255,255,0]; +}else{ +_3d1=dojo.graphics.color.extractRGB(_3d1); +} +return _3d1; +}; +ds.getComputedStyle=function(node,_3d3,_3d4){ +node=dojo.byId(node); +var _3d3=ds.toSelectorCase(_3d3); +var _3d5=ds.toCamelCase(_3d3); +if(!node||!node.style){ +return _3d4; +}else{ +if(document.defaultView){ +try{ +var cs=document.defaultView.getComputedStyle(node,""); +if(cs){ +return cs.getPropertyValue(_3d3); +} +} +catch(e){ +if(node.style.getPropertyValue){ +return node.style.getPropertyValue(_3d3); +}else{ +return _3d4; +} +} +}else{ +if(node.currentStyle){ +return node.currentStyle[_3d5]; +} +} +} +if(node.style.getPropertyValue){ +return node.style.getPropertyValue(_3d3); +}else{ +return _3d4; +} +}; +ds.getStyleProperty=function(node,_3d8){ +node=dojo.byId(node); +return (node&&node.style?node.style[ds.toCamelCase(_3d8)]:undefined); +}; +ds.getStyle=function(node,_3da){ +var _3db=ds.getStyleProperty(node,_3da); +return (_3db?_3db:ds.getComputedStyle(node,_3da)); +}; +ds.setStyle=function(node,_3dd,_3de){ +node=dojo.byId(node); +if(node&&node.style){ +var _3df=ds.toCamelCase(_3dd); +node.style[_3df]=_3de; +} +}; +ds.toCamelCase=function(_3e0){ +var arr=_3e0.split("-"),cc=arr[0]; +for(var i=1;i=1){ +if(h.ie){ +ds.clearOpacity(node); +return; +}else{ +_3e5=0.999999; +} +}else{ +if(_3e5<0){ +_3e5=0; +} +} +} +if(h.ie){ +if(node.nodeName.toLowerCase()=="tr"){ +var tds=node.getElementsByTagName("td"); +for(var x=0;x=0.999999?1:Number(opac); +}; +ds.clearOpacity=function clearOpacity(node){ +node=dojo.byId(node); +var ns=node.style; +if(h.ie){ +try{ +if(node.filters&&node.filters.alpha){ +ns.filter=""; +} +} +catch(e){ +} +}else{ +if(h.moz){ +ns.opacity=1; +ns.MozOpacity=1; +}else{ +if(h.safari){ +ns.opacity=1; +ns.KhtmlOpacity=1; +}else{ +ns.opacity=1; +} +} +} +}; +ds.setStyleAttributes=function(node,_3ee){ +var _3ef={"opacity":dojo.style.setOpacity,"content-height":dojo.style.setContentHeight,"content-width":dojo.style.setContentWidth,"outer-height":dojo.style.setOuterHeight,"outer-width":dojo.style.setOuterWidth}; +var _3f0=_3ee.replace(/(;)?\s*$/,"").split(";"); +for(var i=0;i<_3f0.length;i++){ +var _3f2=_3f0[i].split(":"); +var name=_3f2[0].replace(/\s*$/,"").replace(/^\s*/,"").toLowerCase(); +var _3f4=_3f2[1].replace(/\s*$/,"").replace(/^\s*/,""); +if(dojo.lang.has(_3ef,name)){ +_3ef[name](node,_3f4); +}else{ +node.style[dojo.style.toCamelCase(name)]=_3f4; +} +} +}; +ds._toggle=function(node,_3f6,_3f7){ +node=dojo.byId(node); +_3f7(node,!_3f6(node)); +return _3f6(node); +}; +ds.show=function(node){ +node=dojo.byId(node); +if(ds.getStyleProperty(node,"display")=="none"){ +ds.setStyle(node,"display",(node.dojoDisplayCache||"")); +node.dojoDisplayCache=undefined; +} +}; +ds.hide=function(node){ +node=dojo.byId(node); +if(typeof node["dojoDisplayCache"]=="undefined"){ +var d=ds.getStyleProperty(node,"display"); +if(d!="none"){ +node.dojoDisplayCache=d; +} +} +ds.setStyle(node,"display","none"); +}; +ds.setShowing=function(node,_3fc){ +ds[(_3fc?"show":"hide")](node); +}; +ds.isShowing=function(node){ +return (ds.getStyleProperty(node,"display")!="none"); +}; +ds.toggleShowing=function(node){ +return ds._toggle(node,ds.isShowing,ds.setShowing); +}; +ds.displayMap={tr:"",td:"",th:"",img:"inline",span:"inline",input:"inline",button:"inline"}; +ds.suggestDisplayByTagName=function(node){ +node=dojo.byId(node); +if(node&&node.tagName){ +var tag=node.tagName.toLowerCase(); +return (tag in ds.displayMap?ds.displayMap[tag]:"block"); +} +}; +ds.setDisplay=function(node,_402){ +ds.setStyle(node,"display",(dojo.lang.isString(_402)?_402:(_402?ds.suggestDisplayByTagName(node):"none"))); +}; +ds.isDisplayed=function(node){ +return (ds.getComputedStyle(node,"display")!="none"); +}; +ds.toggleDisplay=function(node){ +return ds._toggle(node,ds.isDisplayed,ds.setDisplay); +}; +ds.setVisibility=function(node,_406){ +ds.setStyle(node,"visibility",(dojo.lang.isString(_406)?_406:(_406?"visible":"hidden"))); +}; +ds.isVisible=function(node){ +return (ds.getComputedStyle(node,"visibility")!="hidden"); +}; +ds.toggleVisibility=function(node){ +return ds._toggle(node,ds.isVisible,ds.setVisibility); +}; +ds.toCoordinateArray=function(_409,_40a){ +if(dojo.lang.isArray(_409)){ +while(_409.length<4){ +_409.push(0); +} +while(_409.length>4){ +_409.pop(); +} +var ret=_409; +}else{ +var node=dojo.byId(_409); +var pos=ds.getAbsolutePosition(node,_40a); +var ret=[pos.x,pos.y,ds.getBorderBoxWidth(node),ds.getBorderBoxHeight(node)]; +} +ret.x=ret[0]; +ret.y=ret[1]; +ret.w=ret[2]; +ret.h=ret[3]; +return ret; +}; +})(); +dojo.provide("dojo.html"); +dojo.require("dojo.lang.func"); +dojo.require("dojo.dom"); +dojo.require("dojo.style"); +dojo.require("dojo.string"); +dojo.lang.mixin(dojo.html,dojo.dom); +dojo.lang.mixin(dojo.html,dojo.style); +dojo.html.clearSelection=function(){ +try{ +if(window["getSelection"]){ +if(dojo.render.html.safari){ +window.getSelection().collapse(); +}else{ +window.getSelection().removeAllRanges(); +} +}else{ +if(document.selection){ +if(document.selection.empty){ +document.selection.empty(); +}else{ +if(document.selection.clear){ +document.selection.clear(); +} +} +} +} +return true; +} +catch(e){ +dojo.debug(e); +return false; +} +}; +dojo.html.disableSelection=function(_40e){ +_40e=dojo.byId(_40e)||document.body; +var h=dojo.render.html; +if(h.mozilla){ +_40e.style.MozUserSelect="none"; +}else{ +if(h.safari){ +_40e.style.KhtmlUserSelect="none"; +}else{ +if(h.ie){ +_40e.unselectable="on"; +}else{ +return false; +} +} +} +return true; +}; +dojo.html.enableSelection=function(_410){ +_410=dojo.byId(_410)||document.body; +var h=dojo.render.html; +if(h.mozilla){ +_410.style.MozUserSelect=""; +}else{ +if(h.safari){ +_410.style.KhtmlUserSelect=""; +}else{ +if(h.ie){ +_410.unselectable="off"; +}else{ +return false; +} +} +} +return true; +}; +dojo.html.selectElement=function(_412){ +_412=dojo.byId(_412); +if(document.selection&&document.body.createTextRange){ +var _413=document.body.createTextRange(); +_413.moveToElementText(_412); +_413.select(); +}else{ +if(window["getSelection"]){ +var _414=window.getSelection(); +if(_414["selectAllChildren"]){ +_414.selectAllChildren(_412); +} +} +} +}; +dojo.html.selectInputText=function(_415){ +_415=dojo.byId(_415); +if(document.selection&&document.body.createTextRange){ +var _416=_415.createTextRange(); +_416.moveStart("character",0); +_416.moveEnd("character",_415.value.length); +_416.select(); +}else{ +if(window["getSelection"]){ +var _417=window.getSelection(); +_415.setSelectionRange(0,_415.value.length); +} +} +_415.focus(); +}; +dojo.html.isSelectionCollapsed=function(){ +if(document["selection"]){ +return document.selection.createRange().text==""; +}else{ +if(window["getSelection"]){ +var _418=window.getSelection(); +if(dojo.lang.isString(_418)){ +return _418==""; +}else{ +return _418.isCollapsed; +} +} +} +}; +dojo.html.getEventTarget=function(evt){ +if(!evt){ +evt=window.event||{}; +} +var t=(evt.srcElement?evt.srcElement:(evt.target?evt.target:null)); +while((t)&&(t.nodeType!=1)){ +t=t.parentNode; +} +return t; +}; +dojo.html.getDocumentWidth=function(){ +dojo.deprecated("dojo.html.getDocument*","replaced by dojo.html.getViewport*","0.4"); +return dojo.html.getViewportWidth(); +}; +dojo.html.getDocumentHeight=function(){ +dojo.deprecated("dojo.html.getDocument*","replaced by dojo.html.getViewport*","0.4"); +return dojo.html.getViewportHeight(); +}; +dojo.html.getDocumentSize=function(){ +dojo.deprecated("dojo.html.getDocument*","replaced of dojo.html.getViewport*","0.4"); +return dojo.html.getViewportSize(); +}; +dojo.html.getViewportWidth=function(){ +var w=0; +if(window.innerWidth){ +w=window.innerWidth; +} +if(dojo.exists(document,"documentElement.clientWidth")){ +var w2=document.documentElement.clientWidth; +if(!w||w2&&w2=left&&_456.x<=_45a&&_456.y>=top&&_456.y<=_458); +}; +dojo.html.setActiveStyleSheet=function(_45b){ +var i=0,a,els=document.getElementsByTagName("link"); +while(a=els[i++]){ +if(a.getAttribute("rel").indexOf("style")!=-1&&a.getAttribute("title")){ +a.disabled=true; +if(a.getAttribute("title")==_45b){ +a.disabled=false; +} +} +} +}; +dojo.html.getActiveStyleSheet=function(){ +var i=0,a,els=document.getElementsByTagName("link"); +while(a=els[i++]){ +if(a.getAttribute("rel").indexOf("style")!=-1&&a.getAttribute("title")&&!a.disabled){ +return a.getAttribute("title"); +} +} +return null; +}; +dojo.html.getPreferredStyleSheet=function(){ +var i=0,a,els=document.getElementsByTagName("link"); +while(a=els[i++]){ +if(a.getAttribute("rel").indexOf("style")!=-1&&a.getAttribute("rel").indexOf("alt")==-1&&a.getAttribute("title")){ +return a.getAttribute("title"); +} +} +return null; +}; +dojo.html.body=function(){ +return document.body||document.getElementsByTagName("body")[0]; +}; +dojo.html.isTag=function(node){ +node=dojo.byId(node); +if(node&&node.tagName){ +var arr=dojo.lang.map(dojo.lang.toArray(arguments,1),function(a){ +return String(a).toLowerCase(); +}); +return arr[dojo.lang.find(node.tagName.toLowerCase(),arr)]||""; +} +return ""; +}; +dojo.html.copyStyle=function(_462,_463){ +if(dojo.lang.isUndefined(_463.style.cssText)){ +_462.setAttribute("style",_463.getAttribute("style")); +}else{ +_462.style.cssText=_463.style.cssText; +} +dojo.html.addClass(_462,dojo.html.getClass(_463)); +}; +dojo.html._callExtrasDeprecated=function(_464,args){ +var _466="dojo.html.extras"; +dojo.deprecated("dojo.html."+_464,"moved to "+_466,"0.4"); +dojo["require"](_466); +return dojo.html[_464].apply(dojo.html,args); +}; +dojo.html.createNodesFromText=function(){ +return dojo.html._callExtrasDeprecated("createNodesFromText",arguments); +}; +dojo.html.gravity=function(){ +return dojo.html._callExtrasDeprecated("gravity",arguments); +}; +dojo.html.placeOnScreen=function(){ +return dojo.html._callExtrasDeprecated("placeOnScreen",arguments); +}; +dojo.html.placeOnScreenPoint=function(){ +return dojo.html._callExtrasDeprecated("placeOnScreenPoint",arguments); +}; +dojo.html.renderedTextContent=function(){ +return dojo.html._callExtrasDeprecated("renderedTextContent",arguments); +}; +dojo.html.BackgroundIframe=function(){ +return dojo.html._callExtrasDeprecated("BackgroundIframe",arguments); +}; +dojo.provide("dojo.lfx.html"); +dojo.require("dojo.lfx.Animation"); +dojo.require("dojo.html"); +dojo.lfx.html._byId=function(_467){ +if(!_467){ +return []; +} +if(dojo.lang.isArray(_467)){ +if(!_467.alreadyChecked){ +var n=[]; +dojo.lang.forEach(_467,function(node){ +n.push(dojo.byId(node)); +}); +n.alreadyChecked=true; +return n; +}else{ +return _467; +} +}else{ +var n=[]; +n.push(dojo.byId(_467)); +n.alreadyChecked=true; +return n; +} +}; +dojo.lfx.html.propertyAnimation=function(_46a,_46b,_46c,_46d){ +_46a=dojo.lfx.html._byId(_46a); +if(_46a.length==1){ +dojo.lang.forEach(_46b,function(prop){ +if(typeof prop["start"]=="undefined"){ +if(prop.property!="opacity"){ +prop.start=parseInt(dojo.style.getComputedStyle(_46a[0],prop.property)); +}else{ +prop.start=dojo.style.getOpacity(_46a[0]); +} +} +}); +} +var _46f=function(_470){ +var _471=new Array(_470.length); +for(var i=0;i<_470.length;i++){ +_471[i]=Math.round(_470[i]); +} +return _471; +}; +var _473=function(n,_475){ +n=dojo.byId(n); +if(!n||!n.style){ +return; +} +for(var s in _475){ +if(s=="opacity"){ +dojo.style.setOpacity(n,_475[s]); +}else{ +n.style[s]=_475[s]; +} +} +}; +var _477=function(_478){ +this._properties=_478; +this.diffs=new Array(_478.length); +dojo.lang.forEach(_478,function(prop,i){ +if(dojo.lang.isArray(prop.start)){ +this.diffs[i]=null; +}else{ +if(prop.start instanceof dojo.graphics.color.Color){ +prop.startRgb=prop.start.toRgb(); +prop.endRgb=prop.end.toRgb(); +}else{ +this.diffs[i]=prop.end-prop.start; +} +} +},this); +this.getValue=function(n){ +var ret={}; +dojo.lang.forEach(this._properties,function(prop,i){ +var _47f=null; +if(dojo.lang.isArray(prop.start)){ +}else{ +if(prop.start instanceof dojo.graphics.color.Color){ +_47f=(prop.units||"rgb")+"("; +for(var j=0;j1){ +return dojo.lfx.combine(_4a2); +}else{ +return _4a2[0]; +} +}; +dojo.lfx.html.wipeOut=function(_4a7,_4a8,_4a9,_4aa){ +_4a7=dojo.lfx.html._byId(_4a7); +var _4ab=[]; +dojo.lang.forEach(_4a7,function(node){ +var _4ad=dojo.style.getStyle(node,"overflow"); +if(_4ad=="visible"){ +node.style.overflow="hidden"; +} +dojo.style.show(node); +var anim=dojo.lfx.propertyAnimation(node,[{property:"height",start:dojo.style.getContentBoxHeight(node),end:0}],_4a8,_4a9); +var _4af=(anim["onEnd"])?dojo.lang.hitch(anim,"onEnd"):function(){ +}; +anim.onEnd=function(){ +_4af(); +dojo.style.hide(node); +node.style.overflow=_4ad; +if(_4aa){ +_4aa(node,anim); +} +}; +_4ab.push(anim); +}); +if(_4a7.length>1){ +return dojo.lfx.combine(_4ab); +}else{ +return _4ab[0]; +} +}; +dojo.lfx.html.slideTo=function(_4b0,_4b1,_4b2,_4b3,_4b4){ +_4b0=dojo.lfx.html._byId(_4b0); +var _4b5=[]; +dojo.lang.forEach(_4b0,function(node){ +var top=null; +var left=null; +var init=(function(){ +var _4ba=node; +return function(){ +top=_4ba.offsetTop; +left=_4ba.offsetLeft; +if(!dojo.style.isPositionAbsolute(_4ba)){ +var ret=dojo.style.abs(_4ba,true); +dojo.style.setStyleAttributes(_4ba,"position:absolute;top:"+ret.y+"px;left:"+ret.x+"px;"); +top=ret.y; +left=ret.x; +} +}; +})(); +init(); +var anim=dojo.lfx.propertyAnimation(node,[{property:"top",start:top,end:_4b1[0]},{property:"left",start:left,end:_4b1[1]}],_4b2,_4b3); +var _4bd=(anim["beforeBegin"])?dojo.lang.hitch(anim,"beforeBegin"):function(){ +}; +anim.beforeBegin=function(){ +_4bd(); +init(); +}; +if(_4b4){ +var _4be=(anim["onEnd"])?dojo.lang.hitch(anim,"onEnd"):function(){ +}; +anim.onEnd=function(){ +_4be(); +_4b4(_4b0,anim); +}; +} +_4b5.push(anim); +}); +if(_4b0.length>1){ +return dojo.lfx.combine(_4b5); +}else{ +return _4b5[0]; +} +}; +dojo.lfx.html.slideBy=function(_4bf,_4c0,_4c1,_4c2,_4c3){ +_4bf=dojo.lfx.html._byId(_4bf); +var _4c4=[]; +dojo.lang.forEach(_4bf,function(node){ +var top=null; +var left=null; +var init=(function(){ +var _4c9=node; +return function(){ +top=node.offsetTop; +left=node.offsetLeft; +if(!dojo.style.isPositionAbsolute(_4c9)){ +var ret=dojo.style.abs(_4c9); +dojo.style.setStyleAttributes(_4c9,"position:absolute;top:"+ret.y+"px;left:"+ret.x+"px;"); +top=ret.y; +left=ret.x; +} +}; +})(); +init(); +var anim=dojo.lfx.propertyAnimation(node,[{property:"top",start:top,end:top+_4c0[0]},{property:"left",start:left,end:left+_4c0[1]}],_4c1,_4c2); +var _4cc=(anim["beforeBegin"])?dojo.lang.hitch(anim,"beforeBegin"):function(){ +}; +anim.beforeBegin=function(){ +_4cc(); +init(); +}; +if(_4c3){ +var _4cd=(anim["onEnd"])?dojo.lang.hitch(anim,"onEnd"):function(){ +}; +anim.onEnd=function(){ +_4cd(); +_4c3(_4bf,anim); +}; +} +_4c4.push(anim); +}); +if(_4bf.length>1){ +return dojo.lfx.combine(_4c4); +}else{ +return _4c4[0]; +} +}; +dojo.lfx.html.explode=function(_4ce,_4cf,_4d0,_4d1,_4d2){ +_4ce=dojo.byId(_4ce); +_4cf=dojo.byId(_4cf); +var _4d3=dojo.style.toCoordinateArray(_4ce,true); +var _4d4=document.createElement("div"); +dojo.html.copyStyle(_4d4,_4cf); +with(_4d4.style){ +position="absolute"; +display="none"; +} +document.body.appendChild(_4d4); +with(_4cf.style){ +visibility="hidden"; +display="block"; +} +var _4d5=dojo.style.toCoordinateArray(_4cf,true); +with(_4cf.style){ +display="none"; +visibility="visible"; +} +var anim=new dojo.lfx.propertyAnimation(_4d4,[{property:"height",start:_4d3[3],end:_4d5[3]},{property:"width",start:_4d3[2],end:_4d5[2]},{property:"top",start:_4d3[1],end:_4d5[1]},{property:"left",start:_4d3[0],end:_4d5[0]},{property:"opacity",start:0.3,end:1}],_4d0,_4d1); +anim.beforeBegin=function(){ +dojo.style.setDisplay(_4d4,"block"); +}; +anim.onEnd=function(){ +dojo.style.setDisplay(_4cf,"block"); +_4d4.parentNode.removeChild(_4d4); +}; +if(_4d2){ +var _4d7=(anim["onEnd"])?dojo.lang.hitch(anim,"onEnd"):function(){ +}; +anim.onEnd=function(){ +_4d7(); +_4d2(_4cf,anim); +}; +} +return anim; +}; +dojo.lfx.html.implode=function(_4d8,end,_4da,_4db,_4dc){ +_4d8=dojo.byId(_4d8); +end=dojo.byId(end); +var _4dd=dojo.style.toCoordinateArray(_4d8,true); +var _4de=dojo.style.toCoordinateArray(end,true); +var _4df=document.createElement("div"); +dojo.html.copyStyle(_4df,_4d8); +dojo.style.setOpacity(_4df,0.3); +with(_4df.style){ +position="absolute"; +display="none"; +} +document.body.appendChild(_4df); +var anim=new dojo.lfx.propertyAnimation(_4df,[{property:"height",start:_4dd[3],end:_4de[3]},{property:"width",start:_4dd[2],end:_4de[2]},{property:"top",start:_4dd[1],end:_4de[1]},{property:"left",start:_4dd[0],end:_4de[0]},{property:"opacity",start:1,end:0.3}],_4da,_4db); +anim.beforeBegin=function(){ +dojo.style.hide(_4d8); +dojo.style.show(_4df); +}; +anim.onEnd=function(){ +_4df.parentNode.removeChild(_4df); +}; +if(_4dc){ +var _4e1=(anim["onEnd"])?dojo.lang.hitch(anim,"onEnd"):function(){ +}; +anim.onEnd=function(){ +_4e1(); +_4dc(_4d8,anim); +}; +} +return anim; +}; +dojo.lfx.html.highlight=function(_4e2,_4e3,_4e4,_4e5,_4e6){ +_4e2=dojo.lfx.html._byId(_4e2); +var _4e7=[]; +dojo.lang.forEach(_4e2,function(node){ +var _4e9=dojo.style.getBackgroundColor(node); +var bg=dojo.style.getStyle(node,"background-color").toLowerCase(); +var _4eb=dojo.style.getStyle(node,"background-image"); +var _4ec=(bg=="transparent"||bg=="rgba(0, 0, 0, 0)"); +while(_4e9.length>3){ +_4e9.pop(); +} +var rgb=new dojo.graphics.color.Color(_4e3); +var _4ee=new dojo.graphics.color.Color(_4e9); +var anim=dojo.lfx.propertyAnimation(node,[{property:"background-color",start:rgb,end:_4ee}],_4e4,_4e5); +var _4f0=(anim["beforeBegin"])?dojo.lang.hitch(anim,"beforeBegin"):function(){ +}; +anim.beforeBegin=function(){ +_4f0(); +if(_4eb){ +node.style.backgroundImage="none"; +} +node.style.backgroundColor="rgb("+rgb.toRgb().join(",")+")"; +}; +var _4f1=(anim["onEnd"])?dojo.lang.hitch(anim,"onEnd"):function(){ +}; +anim.onEnd=function(){ +_4f1(); +if(_4eb){ +node.style.backgroundImage=_4eb; +} +if(_4ec){ +node.style.backgroundColor="transparent"; +} +if(_4e6){ +_4e6(node,anim); +} +}; +_4e7.push(anim); +}); +if(_4e2.length>1){ +return dojo.lfx.combine(_4e7); +}else{ +return _4e7[0]; +} +}; +dojo.lfx.html.unhighlight=function(_4f2,_4f3,_4f4,_4f5,_4f6){ +_4f2=dojo.lfx.html._byId(_4f2); +var _4f7=[]; +dojo.lang.forEach(_4f2,function(node){ +var _4f9=new dojo.graphics.color.Color(dojo.style.getBackgroundColor(node)); +var rgb=new dojo.graphics.color.Color(_4f3); +var _4fb=dojo.style.getStyle(node,"background-image"); +var anim=dojo.lfx.propertyAnimation(node,[{property:"background-color",start:_4f9,end:rgb}],_4f4,_4f5); +var _4fd=(anim["beforeBegin"])?dojo.lang.hitch(anim,"beforeBegin"):function(){ +}; +anim.beforeBegin=function(){ +_4fd(); +if(_4fb){ +node.style.backgroundImage="none"; +} +node.style.backgroundColor="rgb("+_4f9.toRgb().join(",")+")"; +}; +var _4fe=(anim["onEnd"])?dojo.lang.hitch(anim,"onEnd"):function(){ +}; +anim.onEnd=function(){ +_4fe(); +if(_4f6){ +_4f6(node,anim); +} +}; +_4f7.push(anim); +}); +if(_4f2.length>1){ +return dojo.lfx.combine(_4f7); +}else{ +return _4f7[0]; +} +}; +dojo.lang.mixin(dojo.lfx,dojo.lfx.html); +dojo.kwCompoundRequire({browser:["dojo.lfx.html"],dashboard:["dojo.lfx.html"]}); +dojo.provide("dojo.lfx.*"); + diff --git a/source/web/scripts/ajax/node-info.js b/source/web/scripts/ajax/node-info.js new file mode 100644 index 0000000000..cf32ccd503 --- /dev/null +++ b/source/web/scripts/ajax/node-info.js @@ -0,0 +1,73 @@ +// +// Supporting JavaScript for the NodeInfo component +// Gavin Cornwell 17-07-2006 +// + +var _launchElement = null; +var _popupElement = null; + +/** + * Makes the AJAX request back to the server to get the node info. + * + * @param nodeRef The node reference to get information for + * @param launchElement The element that requested the summary panel + */ +function showNodeInfo(nodeRef, launchElement) +{ + _launchElement = launchElement; + + dojo.io.bind({ + method: 'post', + url: WEBAPP_CONTEXT + '/ajax/invoke/NodeInfoBean.sendNodeInfo', + content: { noderef: nodeRef }, + load: showNodeInfoHandler, + error: handleErrorDojo, + mimetype: 'text/html' + }); +} + +/** + * Fades in the summary panel containing the node information. + * This function is called back via the dojo bind call above. + */ +function showNodeInfoHandler(type, data, evt) +{ + // create a 'div' to hold the summary table + var div = document.createElement("div"); + + // get the position of the element we are showing info for + var pos = dojo.style.getAbsolutePosition(_launchElement, false); + + // setup the div with the correct appearance + div.innerHTML = data; + div.setAttribute("class", "summaryPopupPanel"); + // NOTE: use className for IE + div.setAttribute("className", "summaryPopupPanel"); + div.style.position = "absolute"; + div.style.left = pos[0]; + div.style.top = pos[1] + 16; + div.style.zIndex = 99; + + // is there a better way of doing this, dojo.dom.insertBefore?? + var body = document.getElementsByTagName("body")[0]; + dojo.style.setOpacity(div, 0); + _popupElement = div; + body.appendChild(div); + + dojo.lfx.html.fadeIn(div, 300).play(); +} + +/** + * Fades out the summary panel with the node info + * and then removes it from the DOM + */ +function hideNodeInfo() +{ + // remove the node from the DOM and reset variables + dojo.lfx.html.fadeOut(_popupElement, 300, dojo.lfx.easeOut, function(nodes) + { + dojo.lang.forEach(nodes, dojo.dom.removeNode); + _popupElement = null; + _launchElement = null; + }).play(); +}