summaryrefslogtreecommitdiff
path: root/addons/base/static/src
diff options
context:
space:
mode:
authorVidhin Mehta (OpenERP) <vme@tinyerp.com>2011-09-14 11:07:46 +0530
committerVidhin Mehta (OpenERP) <vme@tinyerp.com>2011-09-14 11:07:46 +0530
commitb6076c3cc3ca5141349b99821268b8fd5e148b77 (patch)
treebb875d3ef5127cf5b8c35de6475de14e5477dbbd /addons/base/static/src
parent243e1bdb0079ea9f214696ead8228d464ecb2cfc (diff)
parentc7c2b5846d3775780bbaa9a84a93ad755bdb8756 (diff)
[Merge] upto revno 1024.
bzr revid: vme@tinyerp.com-20110914053746-ri6d5s341mm6tc7n
Diffstat (limited to 'addons/base/static/src')
-rw-r--r--addons/base/static/src/css/base-ie7.css4
-rw-r--r--addons/base/static/src/css/base.css1277
-rw-r--r--addons/base/static/src/css/data_export.css85
-rw-r--r--addons/base/static/src/img/accessories-archiver.pngbin822 -> 0 bytes
-rw-r--r--addons/base/static/src/img/add-shortcut.pngbin395 -> 0 bytes
-rw-r--r--addons/base/static/src/img/attachments-close.pngbin486 -> 0 bytes
-rw-r--r--addons/base/static/src/img/collapse.gifbin80 -> 0 bytes
-rw-r--r--addons/base/static/src/img/db.pngbin2042 -> 0 bytes
-rw-r--r--addons/base/static/src/img/down-arrow.pngbin263 -> 0 bytes
-rw-r--r--addons/base/static/src/img/expand.gifbin81 -> 0 bytes
-rw-r--r--addons/base/static/src/img/favicon.icobin1150 -> 0 bytes
-rw-r--r--addons/base/static/src/img/header-about.pngbin442 -> 0 bytes
-rw-r--r--addons/base/static/src/img/header-background.pngbin149 -> 0 bytes
-rw-r--r--addons/base/static/src/img/header-help.pngbin454 -> 0 bytes
-rw-r--r--addons/base/static/src/img/header-home.pngbin452 -> 0 bytes
-rw-r--r--addons/base/static/src/img/header-preferences.pngbin420 -> 0 bytes
-rw-r--r--addons/base/static/src/img/header-requests.pngbin353 -> 0 bytes
-rw-r--r--addons/base/static/src/img/header.gifbin182 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_ABOUT.pngbin523 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_ADD.pngbin212 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_APPLY.pngbin709 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_BOLD.pngbin604 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_CANCEL.pngbin407 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_CDROM.pngbin711 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_CLEAR.pngbin682 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_CLOSE.pngbin274 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_COLOR_PICKER.pngbin470 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_CONNECT.pngbin558 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_CONVERT.pngbin500 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_COPY.pngbin339 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_CUT.pngbin626 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_DELETE.pngbin531 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_DIALOG_AUTHENTICATION.pngbin590 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_DIALOG_ERROR.pngbin559 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_DIALOG_INFO.pngbin687 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_DIALOG_QUESTION.pngbin491 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_DIALOG_WARNING.pngbin428 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_DIRECTORY.pngbin392 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_DISCONNECT.pngbin566 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_DND.pngbin585 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_DND_MULTIPLE.pngbin501 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_EDIT.pngbin350 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_EXECUTE.pngbin318 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_FILE.pngbin289 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_FIND.pngbin465 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_FIND_AND_REPLACE.pngbin580 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_FLOPPY.pngbin565 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_FULLSCREEN.pngbin450 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_GOTO_BOTTOM.pngbin574 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_GOTO_FIRST.pngbin573 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_GOTO_LAST.pngbin575 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_GOTO_TOP.pngbin580 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_GO_BACK.pngbin570 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_GO_DOWN.pngbin572 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_GO_FORWARD.pngbin575 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_GO_UP.pngbin596 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_HARDDISK.pngbin354 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_HELP.pngbin789 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_HOME.pngbin477 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_INDENT.pngbin276 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_INDEX.pngbin590 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_INFO.pngbin738 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_ITALIC.pngbin529 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_JUMP_TO.pngbin591 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_JUSTIFY_CENTER.pngbin251 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_JUSTIFY_FILL.pngbin243 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_JUSTIFY_LEFT.pngbin240 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_JUSTIFY_RIGHT.pngbin254 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_LEAVE_FULLSCREEN.pngbin448 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_MEDIA_FORWARD.pngbin704 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_MEDIA_NEXT.pngbin693 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_MEDIA_PAUSE.pngbin466 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_MEDIA_PLAY.pngbin556 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_MEDIA_PREVIOUS.pngbin686 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_MEDIA_RECORD.pngbin594 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_MEDIA_REWIND.pngbin704 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_MEDIA_STOP.pngbin421 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_MISSING_IMAGE.pngbin330 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_NETWORK.pngbin324 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_NEW.pngbin405 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_NO.pngbin751 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_OK.pngbin795 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_OPEN.pngbin418 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_PASTE.pngbin473 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_PREFERENCES.pngbin339 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_PRINT.pngbin411 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_PRINT_PREVIEW.pngbin616 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_PROPERTIES.pngbin313 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_QUIT.pngbin394 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_REDO.pngbin430 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_REFRESH.pngbin753 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_REMOVE.pngbin176 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_REVERT_TO_SAVED.pngbin413 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_SAVE.pngbin599 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_SAVE_AS.pngbin560 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_SELECT_COLOR.pngbin656 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_SELECT_FONT.pngbin598 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_SORT_ASCENDING.pngbin371 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_SORT_DESCENDING.pngbin370 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_SPELL_CHECK.pngbin485 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_STOP.pngbin678 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_STRIKETHROUGH.pngbin459 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_UNDELETE.pngbin875 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_UNDERLINE.pngbin539 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_UNDO.pngbin459 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_UNINDENT.pngbin295 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_YES.pngbin830 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_ZOOM_100.pngbin469 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_ZOOM_FIT.pngbin466 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_ZOOM_IN.pngbin446 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/STOCK_ZOOM_OUT.pngbin463 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-add.pngbin212 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-apply.pngbin709 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-cancel.pngbin407 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-close.pngbin274 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-convert.pngbin500 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-delete.pngbin531 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-dnd.pngbin585 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-edit.pngbin350 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-execute.pngbin318 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-find.pngbin465 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-go-back.pngbin570 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-go-down.pngbin572 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-go-forward.pngbin575 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-go-up.pngbin596 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-goto-last.pngbin575 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-indent.pngbin276 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-index.pngbin590 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-jump-to.pngbin591 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-justify-fill.pngbin243 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-media-pause.pngbin466 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-media-play.pngbin556 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-network.pngbin324 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-new.pngbin405 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-no.pngbin751 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-ok.pngbin795 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-open.pngbin418 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-print.pngbin411 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-redo.pngbin430 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-remove.pngbin176 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-save.pngbin599 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-sort-descending.pngbin370 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-stop.pngbin678 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-undo.pngbin459 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-yes.pngbin830 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-zoom-fit.pngbin466 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/gtk-zoom-in.pngbin446 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/index1.jpegbin473 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/index2.jpegbin471 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-accessories-archiver+.pngbin838 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-accessories-archiver-minus.pngbin838 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-accessories-archiver.pngbin822 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-account.pngbin784 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-administration.pngbin1015 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-calendar.pngbin908 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-call-start.pngbin492 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-camera_test.pngbin739 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-check.pngbin832 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-crm.pngbin877 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-dialog-close.pngbin305 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-document-new.pngbin738 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-dolar.pngbin270 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-dolar_ok!.pngbin220 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-emblem-important.pngbin703 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-face-plain.pngbin788 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-folder-blue.pngbin438 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-folder-green.pngbin453 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-folder-orange.pngbin411 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-folder-violet.pngbin538 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-folder-yellow.pngbin432 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-gdu-smart-failing.pngbin451 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-gnome-cpu-frequency-applet+.pngbin488 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-go-home.pngbin378 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-go-month.pngbin517 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-go-today.pngbin501 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-go-week.pngbin442 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-go-year.pngbin514 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-graph.pngbin784 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-gtk-go-back-ltr.pngbin759 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-gtk-go-back-rtl.pngbin762 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-gtk-jump-to-ltr.pngbin859 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-gtk-jump-to-rtl.pngbin851 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-gtk-media-pause.pngbin544 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-gtk-select-all.pngbin554 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-gtk-stop.pngbin622 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-hr.pngbin699 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-idea.pngbin384 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-locked.pngbin588 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-mail-.pngbin427 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-mail-forward.pngbin382 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-mail-message-new.pngbin696 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-mail-replied.pngbin637 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-mail_delete.pngbin988 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-marketing.pngbin808 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-mrp.pngbin880 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-partner.pngbin905 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-personal+.pngbin735 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-personal-.pngbin791 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-personal.pngbin930 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-product.pngbin708 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-project.pngbin993 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-purchase.pngbin885 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-rating-rated.pngbin559 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-report.pngbin831 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-sale.pngbin699 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-stage.pngbin742 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-stock.pngbin967 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-stock_align_left_24.pngbin358 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-stock_effects-object-colorize.pngbin173 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-stock_format-default.pngbin267 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-stock_format-scientific.pngbin201 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-stock_symbol-selection.pngbin382 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-stock_zoom.pngbin425 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-tools.pngbin914 -> 0 bytes
-rw-r--r--addons/base/static/src/img/icons/terp-translate.pngbin519 -> 0 bytes
-rw-r--r--addons/base/static/src/img/iconset-d-drop.gifbin238 -> 0 bytes
-rw-r--r--addons/base/static/src/img/logo.pngbin3551 -> 0 bytes
-rw-r--r--addons/base/static/src/img/partner.pngbin905 -> 0 bytes
-rw-r--r--addons/base/static/src/img/placeholder.pngbin1362 -> 0 bytes
-rw-r--r--addons/base/static/src/img/product.pngbin708 -> 0 bytes
-rw-r--r--addons/base/static/src/img/remove-shortcut.pngbin559 -> 0 bytes
-rw-r--r--addons/base/static/src/img/stock_person.pngbin1074 -> 0 bytes
-rw-r--r--addons/base/static/src/img/throbber.gifbin673 -> 0 bytes
-rw-r--r--addons/base/static/src/img/throbber2.gifbin7195 -> 0 bytes
-rw-r--r--addons/base/static/src/img/toggle-a-bg.pngbin412 -> 0 bytes
-rw-r--r--addons/base/static/src/img/ui/field_calendar.pngbin454 -> 0 bytes
-rw-r--r--addons/base/static/src/img/ui/group-expanded.pngbin229 -> 0 bytes
-rw-r--r--addons/base/static/src/img/ui/group-folded.pngbin259 -> 0 bytes
-rw-r--r--addons/base/static/src/img/warning.pngbin1342 -> 0 bytes
-rw-r--r--addons/base/static/src/js/boot.js67
-rw-r--r--addons/base/static/src/js/chrome.js940
-rw-r--r--addons/base/static/src/js/core.js915
-rw-r--r--addons/base/static/src/js/data.js787
-rw-r--r--addons/base/static/src/js/data_export.js402
-rw-r--r--addons/base/static/src/js/dates.js138
-rw-r--r--addons/base/static/src/js/form.js2477
-rw-r--r--addons/base/static/src/js/formats.js197
-rw-r--r--addons/base/static/src/js/list-editable.js324
-rw-r--r--addons/base/static/src/js/list.js1467
-rw-r--r--addons/base/static/src/js/search.js1177
-rw-r--r--addons/base/static/src/js/view_editor.js147
-rw-r--r--addons/base/static/src/js/view_help.js15
-rw-r--r--addons/base/static/src/js/view_tree.js206
-rw-r--r--addons/base/static/src/js/views.js791
-rw-r--r--addons/base/static/src/xml/base.xml1401
245 files changed, 0 insertions, 12817 deletions
diff --git a/addons/base/static/src/css/base-ie7.css b/addons/base/static/src/css/base-ie7.css
deleted file mode 100644
index 35599dbdd4b..00000000000
--- a/addons/base/static/src/css/base-ie7.css
+++ /dev/null
@@ -1,4 +0,0 @@
-
-.openerp .menu span {
- min-width: 0px;
-}
diff --git a/addons/base/static/src/css/base.css b/addons/base/static/src/css/base.css
deleted file mode 100644
index c9894e42cef..00000000000
--- a/addons/base/static/src/css/base.css
+++ /dev/null
@@ -1,1277 +0,0 @@
-/* TODO: separate openerp web client page css from openerp views css */
-body.openerp {
- padding: 0;
- margin: 0;
- height: 100%;
- min-width: 1000px;
- overflow-y: scroll;
- font-size: 80%;
-}
-
-body.openerp, .openerp textarea, .openerp input, .openerp select, .openerp option, .openerp button, .openerp .ui-widget {
- font-family: Ubuntu, Helvetica, sans-serif;
-}
-
-.oe_box {
- border: 1px solid #aaf;
- padding: 2px;
- margin: 2px;
-}
-
-#oe_header h2 {
- margin: 2px 0;
-}
-
-#oe_errors pre {
- margin: 0;
-}
-
-.openerp .oe-number {
- text-align: right !important;
-}
-.openerp .oe_hide {
- display: none !important;
-}
-
-/* STATES */
-.openerp .on_logged,
-.openerp .db_options_row {
- display: none;
-}
-
-/* Loading */
-.openerp .loading {
- display: none;
- z-index: 100;
- position: fixed;
- top: 0;
- right: 50%;
- padding: 4px 12px;
- background: #A61300;
- color: white;
- text-align: center;
- border: 1px solid #900;
- border-top: none;
- -moz-border-radius-bottomright: 8px;
- -moz-border-radius-bottomleft: 8px;
- border-bottom-right-radius: 8px;
- border-bottom-left-radius: 8px;
-}
-.openerp .oe_notification {
- z-index: 1001;
- display: none;
-}
-.openerp .oe_notification * {
- color: white;
-}
-
-/* Login */
-.openerp .login {
- display: none;
-}
-.openerp .login form {
- float: left;
- width: 420px;
- margin-left: 40px;
- margin-bottom: 60px;
-}
-.openerp .login fieldset {
- padding-bottom: 5px;
- min-width: 100px;
- margin-top: 60px;
- border-radius: 10px;
- -moz-border-radius: 10px;
- -webkit-border-radius: 10px;
-}
-.openerp .login fieldset legend {
- padding: 4px;
-}
-.openerp .login .oe_box2 {
- padding: 5px 5px 20px 5px;
-}
-.openerp .login .oe_box2 table {
- width: 100%;
- border:none;
-}
-.openerp .login .oe_box2 td {
- padding: 3px;
- text-align: right;
-}
-.openerp .login .oe_box2 td input,
-.openerp .login .oe_box2 td select {
- width: 100%;
-}
-.openerp .login .oe_box2 td.oe_remember {
- text-align:left;
-}
-.openerp .login .oe_box2 td.oe_remember input {
- width: inherit;
-}
-.openerp .login .oe_login_right_pane {
- padding:70px 35px 5px 10px;
- min-width: 200px;
- margin-left: 500px;
-}
-.openerp .login .login_error_message {
- display: none;
- background-color: #9A0404;
- border-radius: 3px;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- color: white;
- font-size: 16px;
- font-weight: bold;
- padding: 5px;
- margin-top: 5px;
- text-align: center;
-}
-.openerp .login.login_invalid .login_error_message {
- display: block;
-}
-
-.openerp.login-mode .login-container {
- height: 100%;
-}
-.openerp.login-mode .login {
- display: block;
-}
-.openerp.login-mode .menu,
-.openerp.login-mode .secondary_menu,
-.openerp.login-mode .oe-application,
-.openerp.login-mode .db_options_row {
- display: none;
-}
-
-/* Database */
-.openerp.database_block .db_options_row {
- height: 100%;
- display: table-row;
-}
-
-.openerp.database_block .menu,
-.openerp.database_block .secondary_menu,
-.openerp.database_block .oe-application,
-.openerp.database_block .login-container {
- display: none;
-}
-
-.db_container {
- width: 15%;
- background: #666666;
-}
-
-ul.db_options li {
- padding: 5px 0 10px 5px;
- background: #949292; /* Old browsers */
- background: -moz-linear-gradient(top, #949292 30%, #6d6b6b 95%, #282828 100%); /* FF3.6+ */
- background: -webkit-gradient(linear, left top, left bottom, color-stop(30%,#949292), color-stop(95%,#6d6b6b), color-stop(100%,#282828)); /* Chrome,Safari4+ */
- background: -webkit-linear-gradient(top, #949292 30%,#6d6b6b 95%,#282828 100%); /* Chrome10+,Safari5.1+ */
- background: -o-linear-gradient(top, #949292 30%,#6d6b6b 95%,#282828 100%); /* Opera11.10+ */
- background: -ms-linear-gradient(top, #949292 30%,#6d6b6b 95%,#282828 100%); /* IE10+ */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#949292', endColorstr='#282828',GradientType=0 ); /* IE6-9 */
- background: linear-gradient(top, #949292 30%,#6d6b6b 95%,#282828 100%); /* W3C */
- /* for ie9 */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#949292', endColorstr='#5B5A5A',GradientType=0 ); /* IE6-9 */
- border: none;
- /* overriding jquery ui */
- -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px;
- display: block;
- font-weight: bold;
- text-transform: uppercase;
- margin: 1px;
- color: #EEEEEE;
- cursor: pointer;
- width: 196px;
- font-size: 12px;
-}
-
-.db_option_table {
- border: 1px solid #5A5858;
- padding: 5px;
- -moz-border-radius: 10px;
-}
-
-table.db_option_table input.required {
- background-color: #D2D2FF !important;
-}
-
-.db_option_table input[type="text"], .db_option_table input[type="password"], .db_option_table select {
- width: 300px;
-}
-
-.option_string {
- font-weight: bold;
- color: #555;
- width: 100%;
- text-align: center;
- padding: 10px 0;
- font-size: large;
-}
-
-label.error {
- float: none;
- color: red;
- padding-left: .5em;
- vertical-align: top;
-}
-
-/* Main*/
-.openerp .main_table {
- width: 100%;
- height: 100%;
- background: #f0eeee;
-}
-
-/* Menu */
-.openerp .sf-menu {
- margin-bottom: 0;
-}
-/*
-.sf-menu a {
- padding: 5px 5px;
-}
-*/
-
-.openerp .menu {
- height: 34px;
- background: #cc4e45; /* Old browsers */
- background: -moz-linear-gradient(top, #cc4e45 0%, #b52d20 8%, #7a211a 100%); /* FF3.6+ */
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#cc4e45), color-stop(8%,#b52d20), color-stop(100%,#7a211a)); /* Chrome,Safari4+ */
- background: -webkit-linear-gradient(top, #cc4e45 0%,#b52d20 8%,#7a211a 100%); /* Chrome10+,Safari5.1+ */
- background: -o-linear-gradient(top, #cc4e45 0%,#b52d20 8%,#7a211a 100%); /* Opera11.10+ */
- background: -ms-linear-gradient(top, #cc4e45 0%,#b52d20 8%,#7a211a 100%); /* IE10+ */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#CC4E45', endColorstr='#7A211A',GradientType=0 ); /* IE6-9 */
- background: linear-gradient(top, #cc4e45 0%,#b52d20 8%,#7a211a 100%); /* W3C */
-}
-.openerp .menu td {
- text-align: center;
- padding:0;
-}
-.openerp .menu a {
- display:block;
- min-width: 60px;
- height: 20px;
- margin: 3px 2px;
- padding: 0 8px;
-
- background: #bd5e54; /* Old browsers */
- background: -moz-linear-gradient(top, #bd5e54 0%, #90322a 60%); /* FF3.6+ */
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#bd5e54), color-stop(60%,#90322a)); /* Chrome,Safari4+ */
- background: -webkit-linear-gradient(top, #bd5e54 0%,#90322a 60%); /* Chrome10+,Safari5.1+ */
- background: -o-linear-gradient(top, #bd5e54 0%,#90322a 60%); /* Opera11.10+ */
- background: -ms-linear-gradient(top, #bd5e54 0%,#90322a 60%); /* IE10+ */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#BD5E54', endColorstr='#90322A',GradientType=0 ); /* IE6-9 */
- background: linear-gradient(top, #bd5e54 0%,#90322a 60%); /* W3C */
-
- border: 1px solid #6E2A24;
- border-radius: 4px;
- -moz-border-radius: 4px;
- -webkit-border-radius: 4px;
-
- color: #eee;
- text-shadow: #222 0 1px 0;
- text-decoration: none;
- text-transform: uppercase;
- line-height: 20px;
- font-weight: bold;
- font-size: 85%;
-
- white-space: nowrap;
-}
-.openerp .menu a:hover,
-.openerp .menu a:focus,
-.openerp .menu a.active {
- background: #c6c6c6; /* Old browsers */
- background: -moz-linear-gradient(top, #c6c6c6 0%, #5c5c5c 7%, #969595 86%); /* FF3.6+ */
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#c6c6c6), color-stop(7%,#5c5c5c), color-stop(86%,#969595)); /* Chrome,Safari4+ */
- background: -webkit-linear-gradient(top, #c6c6c6 0%,#5c5c5c 7%,#969595 86%); /* Chrome10+,Safari5.1+ */
- background: -o-linear-gradient(top, #c6c6c6 0%,#5c5c5c 7%,#969595 86%); /* Opera11.10+ */
- background: -ms-linear-gradient(top, #c6c6c6 0%,#5c5c5c 7%,#969595 86%); /* IE10+ */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#C6C6C6', endColorstr='#969595',GradientType=0 ); /* IE6-9 */
- background: linear-gradient(top, #c6c6c6 0%,#5c5c5c 7%,#969595 86%); /* W3C */
- /* for ie */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#5c5c5c', endColorstr='#969595',GradientType=0 ); /* IE6-9 */
-
- color: #fff;
-}
-/* Secondary Menu */
-.openerp .secondary_menu {
- width: 200px;
- min-width: 200px;
- border-right: 1px solid #3C3C3C;
- border-bottom: 1px solid #5A5858;
- background: #5A5858;
- vertical-align: top;
- height: 100%;
-}
-.openerp .secondary_menu .menu_content {
- padding: 0;
- border: none;
- background: none;
- overflow: hidden;
-}
-.openerp .secondary_menu h3 {
- padding: 0 0 2px;
- background: #949292; /* Old browsers */
- background: -moz-linear-gradient(top, #949292 0%, #6d6b6b 87%, #282828 99%); /* FF3.6+ */
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#949292), color-stop(87%,#6d6b6b), color-stop(99%,#282828)); /* Chrome,Safari4+ */
- background: -webkit-linear-gradient(top, #949292 0%,#6d6b6b 87%,#282828 99%); /* Chrome10+,Safari5.1+ */
- background: -o-linear-gradient(top, #949292 0%,#6d6b6b 87%,#282828 99%); /* Opera11.10+ */
- background: -ms-linear-gradient(top, #949292 0%,#6d6b6b 87%,#282828 99%); /* IE10+ */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#949292', endColorstr='#282828',GradientType=0 ); /* IE6-9 */
- background: linear-gradient(top, #949292 0%,#6d6b6b 87%,#282828 99%); /* W3C */
- /* for ie9 */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#949292', endColorstr='#5B5A5A',GradientType=0 ); /* IE6-9 */
- border: none;
- /* overriding jquery ui */
- -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px;
-}
-.openerp .secondary_menu h4 {
- padding: 0 0 2px 10px;
- border: none;
- background: none;
-}
-.openerp .secondary_menu h3 span, .openerp .secondary_menu h4 span {
- left: 0 !important;
-}
-.openerp .secondary_menu a {
- display: block;
- height: 20px;
- padding: 0 5px;
- line-height: 20px;
- white-space: nowrap;
- color: white;
- text-decoration: none;
- text-shadow: 0 1px 0 #333;
-}
-.openerp .secondary_menu a.leaf:hover,
-.openerp .secondary_menu a.leaf:active,
-.openerp .secondary_menu a.leaf.active,
-.openerp .secondary_menu h4:hover,
-.openerp .secondary_menu h4:active,
-.openerp .secondary_menu h4.active {
- background: #ffffff; /* Old browsers */
- background: -moz-linear-gradient(top, #ffffff 0%, #d8d8d8 11%, #afafaf 86%, #333333 91%, #5a5858 96%); /* FF3.6+ */
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(11%,#d8d8d8), color-stop(86%,#afafaf), color-stop(91%,#333333), color-stop(96%,#5a5858)); /* Chrome,Safari4+ */
- background: -webkit-linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%,#5a5858 96%); /* Chrome10+,Safari5.1+ */
- background: -o-linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%,#5a5858 96%); /* Opera11.10+ */
- background: -ms-linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%,#5a5858 96%); /* IE10+ */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFFFFF', endColorstr='#5A5858',GradientType=0 ); /* IE6-9 */
- background: linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%,#5a5858 96%); /* W3C */
- /* overriding jquery ui */
- -moz-border-radius-topright: 0; -webkit-border-top-right-radius: 0; border-top-right-radius: 0;
- color: #3f3d3d;
- text-shadow: #fff 0 1px 0;
- border: none !important;
-}
-
-.openerp .secondary_menu h4:hover a,
-.openerp .secondary_menu h4:active a,
-.openerp .secondary_menu h4.active a {
- color: #3f3d3d;
- text-shadow: #fff 0 1px 0;
- border: none !important;
-}
-.openerp div.submenu_accordion div.menu_content a span {
- padding-left: 20px;
-}
-
-/* Header */
-.openerp .header {
- height: 65px;
- background: url("/base/static/src/img/header-background.png") repeat-x scroll left top transparent;
- color: #FFFFFF;
- letter-spacing: 0.5px;
- text-shadow: 0 1px 0 #333333;
-}
-.openerp .company_logo_link {
- display: block;
- float: left;
- height: 63px;
- width: 200px;
- border: 1px solid white;
- border-right-color: black;
- border-bottom-color: black;
- background: #FFFFFF;
- background: -moz-linear-gradient(top, #FFFFFF 0%, #CECECE 100%);
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FFFFFF), color-stop(100%,#CECECE));
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFFFFF', endColorstr='#CECECE',GradientType=0 );
-}
-.openerp .company_logo {
- margin-top: 7px;
- margin-left: 10px;
- display: block;
- background: url(/base/static/src/img/logo.png);
- width:180px;
- height:46px;
-}
-.openerp .header_title {
- float: left;
- font-size: 100%;
- margin: 0;
- padding: 4px 0;
- text-shadow: 0 1px 0 #111111;
-}
-.openerp .header_title small {
- color: #ccc;
- font-size: 90%;
- font-weight: normal;
-}
-.openerp .header_corner {
- float: right;
-}
-.openerp .header_corner .block {
- float: left;
- height: 34px;
- line-height: 34px;
- /*background: url(../images/top-sep-a.png) no-repeat;*/
- border-left: 1px solid #6a6a6a;
- background: #828282;
- background: -moz-linear-gradient(top, #828282 0%, #4D4D4D 100%);
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#828282), color-stop(100%,#4D4D4D));
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#828282', endColorstr='#4D4D4D',GradientType=0 );
-}
-.openerp .header_corner .block a {
- display: block;
- color: white;
- text-decoration: none;
- padding: 0 10px;
-}
-.openerp .header_corner .block a:hover {
- background: #929292;
- background: -moz-linear-gradient(top, #929292 0%, #4D4D4D 100%);
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#929292), color-stop(100%,#4D4D4D));
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#929292', endColorstr='#4D4D4D',GradientType=0 );
-}
-.openerp .header_corner ul.block {
- /*float: left;*/
- list-style: none;
- height: 34px;
- margin: 0;
- padding: 0 0 0 2px;
- /*background: url(../images/top-sep-a.png) no-repeat;*/
- line-height: 33px;
- /*font-size: 1em;*/
- /*text-transform: uppercase;*/
-}
-.openerp .header_corner ul.block li {
- float: left;
-}
-.openerp .header_corner ul.block li a {
- padding: 0 5px;
- position: relative;
- line-height: 32px;
-}
-.openerp .header_corner ul.block li a img {
- vertical-align: middle;
-}
-.openerp .header_corner ul.block li a small {
- position: absolute;
- right: 0;
- top: 5px;
- padding: 1px 4px 2px;
- background: rgba(0, 0, 0, 0.75);
- border-radius: 7px;
- -moz-border-radius: 7px;
- -webkit-border-radius: 7px;
- line-height: 1em;
- font-weight: bold;
-}
-
-/* Footer */
-.openerp div.oe_footer {
- background: none repeat scroll 0 0 #CCCCCC;
- overflow: hidden;
- padding: 5px 0;
- position: relative;
- -moz-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.4);
- -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.4);
- box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.4);
-}
-.openerp div.oe_footer p.oe_footer_powered {
- left: 50%;
- margin: 0;
- padding: 0 15px;
- color: #666666;
- font-weight: bold;
- font-size: 0.8em;
- text-align: center;
-}
-.openerp div.oe_footer p.oe_footer_powered a {
- text-decoration: none;
- color: #666666;
-}
-
-/* Main Application */
-.openerp .oe-main-content,
-.openerp .oe-application {
- padding: 0;
- height: 100%;
-}
-
-.openerp h2.oe_view_title {
- font-size: 175%;
- font-weight: normal;
- margin: 2px 0;
- color: #252424;
- text-shadow: white 0 1px 0;
-}
-
-/* View Manager */
-.openerp .oe_vm_switch {
- float: right;
-}
-
-/* SearchView */
-.openerp .filter_label, .openerp .filter_icon {
- border: 1px solid #666;
- border-left-width: 0;
- background: #F0F0F0;
- background: -moz-linear-gradient(top, #F0F0F0 0%, #C0C0C0 100%);
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#F0F0F0), color-stop(100%,#C0C0C0));
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#F0F0F0', endColorstr='#C0C0C0',GradientType=0 );
-}
-.openerp .filter_label:hover, .openerp .filter_icon:hover {
- background: #F0F0F0;
- background: -moz-linear-gradient(top, #F0F0F0 0%, #A1A7CE 100%);
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#F0F0F0), color-stop(100%,#A1A7CE));
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#F0F0F0', endColorstr='#A1A7CE',GradientType=0 );
-}
-.openerp .filter_label:active, .openerp .filter_icon:active {
- background: #AAAAAA;
- background: -moz-linear-gradient(top, #999999 0%, #EEEEEE 100%);
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#999999), color-stop(100%,#EEEEEE));
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#999999', endColorstr='#EEEEEE',GradientType=0 );
-}
-.openerp .filter_label.enabled, .openerp .filter_icon.enabled {
- background: #AAAAAA;
-}
-.openerp .filter_icon {
- height: 22px;
- padding: 1px 2px 0 2px;
- margin: 0;
- vertical-align: bottom;
-}
-.openerp .filter_label {
- font-weight: bold;
- text-transform: uppercase;
- text-shadow: #EEE 0 1px 0;
- color: #4C4C4C;
- white-space: nowrap;
- min-height: 40px;
- min-width: 75px;
- padding: 2px 4px;
- margin: 0;
-}
-.openerp .filter_label_group {
- padding-right: 0.4em;
- white-space: nowrap;
-}
-.openerp .filter_label_group button:first-child {
- border-left: 1px solid #666;
- -webkit-border-top-left-radius: 7px;
- -webkit-border-bottom-left-radius: 7px;
- -moz-border-radius-topleft: 7px;
- -moz-border-radius-bottomleft: 7px;
- border-top-left-radius: 7px;
- border-bottom-left-radius: 7px;
-}
-.openerp .filter_label_group button:last-child {
- -webkit-border-top-right-radius: 7px;
- -webkit-border-bottom-right-radius: 7px;
- -moz-border-radius-topright: 7px;
- -moz-border-radius-bottomright: 7px;
- border-top-right-radius: 7px;
- border-bottom-right-radius: 7px;
-}
-
-.openerp .searchview_group_string {
- display: block;
- color: #7D7979;
- font-weight: bold;
- padding: 2px 0 2px 10px;
- margin-top: 4px;
- text-decoration: none;
-}
-.openerp .searchview_group_string:hover {
- background-color: #ccc;
-}
-.openerp .searchview_group.folded .searchview_group_string {
- background: url("/base/static/src/img/ui/group-folded.png") no-repeat scroll 0 50%;
-}
-.openerp .searchview_group.folded .searchview_group_content {
- display: none;
-}
-.openerp .searchview_group.expanded .searchview_group_string {
- background: url("/base/static/src/img/ui/group-expanded.png") no-repeat scroll 0 50%;
-}
-.openerp .searchview_group.expanded .searchview_group_content {
- display: block;
-}
-.openerp .searchview_group_content {
- padding-left: 10px;
-}
-
-.openerp .searchview_extended_group {
- padding: 3px;
- margin: 2px;
-}
-
-.openerp .searchview_extended_group .oe_adv_filters_and {
- border-bottom: 1px solid #8E8E8E;
- text-align: center;
- margin-top: -10px;
-}
-.openerp .searchview_extended_group .oe_adv_filters_and span {
- background: #F0EEEE;
- position: relative;
- top: 0.5em;
- padding: 0 1em 0 1em;
- color: #8E8E8E;
-}
-
-.openerp .searchview_extended_group.last_group .oe_adv_filters_and {
- display: none;
-}
-
-.openerp .oe_search-view-custom-filter-btn span {
- background: url(/base/static/src/img/icons/gtk-add.png) repeat-y;
- padding-left: 18px;
-}
-
-.openerp .searchview_extended_add_proposition span {
- font-size: 0.9em;
- background: url(/base/static/src/img/icons/gtk-add.png) repeat-y;
- padding-left: 18px;
-}
-
-.openerp .searchview_extended_delete_group {
- float:right;
- display: none;
-}
-
-.openerp .searchview_extended_delete_prop {
- text-decoration: none;
-}
-
-.openerp .searchview_extended_delete_group span,
-.openerp .searchview_extended_delete_prop span {
- font-size: 0.9em;
- background: url(/base/static/src/img/icons/gtk-close.png) repeat-y;
- padding-left: 18px;
-}
-/* List */
-.openerp .oe-listview table {
- clear: right;
- width: 100%;
- border-spacing: 0;
- border: 1px solid silver;
-}
-
-.openerp .oe-listview thead table {
- width: 100%;
- border: none;
-}
-.openerp .oe-listview tr.odd {
- background-color: #f3f3f3;
-}
-.openerp .oe-listview tbody tr:hover {
- background-color: #ecebf2;
-}
-.openerp .oe-listview tbody tr:hover {
- background-color: #eae9f0;
-}
-.openerp .oe-listview thead table tr,
-.openerp .oe-listview thead table tr:hover {
- background: none;
-}
-
-.openerp .oe-listview td,
-.openerp .oe-listview th {
- vertical-align: middle;
- text-align: left;
-}
-.openerp .oe-listview td.oe-record-delete {
- text-align: right;
-}
-.openerp .oe-listview th.oe-sortable {
- cursor: pointer;
-}
-.openerp .oe-listview th.oe-sortable .ui-icon {
- height: 1em;
- display: inline;
- display: inline-block;
-}
-
-.openerp .oe-listview .oe-field-cell {
- cursor: pointer;
-}
-.openerp .oe-listview .oe-field-cell button {
- padding: 0;
- border: none;
- background: none;
- width: 100%;
-}
-.openerp .oe-listview .oe-field-cell button:active {
- opacity: 0.5;
-}
-.openerp .oe-listview .oe-field-cell button img {
- cursor: pointer;
-}
-.openerp .oe-listview .oe-field-cell button img:hover {
- opacity: 0.75;
-}
-
-.openerp .oe-listview th.oe-actions {
- text-align: left;
- white-space: nowrap;
-}
-.openerp .oe-listview th.oe-list-pager {
- text-align: right;
- white-space: nowrap;
-}
-.openerp .oe-list-pager .oe-pager-state {
- cursor: pointer;
-}
-
-.openerp .oe-listview .oe-group-name {
- padding-right: 1em;
-}
-.openerp .oe-listview .oe-group-name,
-.openerp .oe-listview .oe-group-pagination {
- white-space: nowrap;
-}
-
-.openerp .oe-listview tfoot td {
- padding: 3px 3px 0;
-}
-.openerp .oe-listview .oe-list-footer {
- text-align: center;
- white-space: nowrap;
-}
-.openerp .oe-listview .oe-list-footer span {
- margin: 0 1em;
-}
-
-/** list rounded corners
-
- rounded corners are a pain on tables: need to round not only table, but
- also on the first and last children of the first and last row
- */
-.openerp .oe-listview table.oe-listview-content {
- -webkit-border-radius: 7px;
- -moz-border-radius: 7px;
- border-radius: 7px;
-}
-.openerp .oe-listview table.oe-listview-content thead tr:first-child th:first-child {
- -webkit-border-top-left-radius: 7px;
- -moz-border-radius-topleft: 7px;
- border-top-left-radius: 7px;
-}
-.openerp .oe-listview table.oe-listview-content thead tr:first-child th:last-child {
- -webkit-border-top-right-radius: 7px;
- -moz-border-radius-topright: 7px;
- border-top-right-radius: 7px;
-}
-.openerp .oe-listview table.oe-listview-content tfoot td:first-child,
-.openerp .oe-listview table.oe-listview-content tbody:last-child tr:last-child th:first-child {
- -webkit-border-bottom-left-radius: 7px;
- -moz-border-radius-bottomleft: 7px;
- border-bottom-left-radius: 7px;
-}
-.openerp .oe-listview table.oe-listview-content tfoot td:last-child,
-.openerp .oe-listview table.oe-listview-content tbody:last-child tr:last-child td:last-child {
- -webkit-border-bottom-right-radius: 7px;
- -moz-border-radius-bottomright: 7px;
- border-bottom-right-radius: 7px;
-}
-
-/* Notebook */
-.openerp .oe_form_notebook {
- padding: 0;
- background: none;
- border-width: 0;
-}
-.openerp .oe_form_notebook ul.ui-tabs-nav {
- padding-left: 0;
- background: transparent;
- border-width: 0 0 1px 0;
- border-radius: 0;
- -moz-border-radius: 0;
- -webkit-border-radius: 0;
- line-height: 0.5em;
-}
-.openerp .oe_form_notebook ul.ui-tabs-nav li {
- font-weight: bold;
-}
-.openerp .oe_form_notebook .ui-tabs-panel {
- background: #f9f9f9;
- border-width: 0 1px 1px 1px;
-}
-.openerp .oe_form_notebook .ui-tabs-selected {
- background: #f9f9f9;
-}
-
-/* Form */
-.openerp table.oe_frame td {
- color: #4c4c4c;
-}
-.openerp td.oe_form_frame_cell {
- padding: 2px;
-}
-.openerp td.oe_form_frame_cell.oe_form_group {
- padding: 0px;
-}
-.openerp .required.error {
- border: 1px solid #900;
-}
-.openerp .oe_form_buttons, .openerp .oe_list_buttons {
- float: left;
-}
-.openerp .oe_form_pager, .openerp .oe_list_pager {
- float: right;
-}
-
-.openerp label.oe_label_help, .openerp label.oe_label {
- display: block;
-}
-.openerp label.oe_label_help {
- cursor: help;
-}
-.openerp .oe_form_field label.oe_label, .openerp .oe_form_field label.oe_label_help {
- text-align: right;
- margin: 3px 0 0 10px;
-}
-.openerp label.oe_label_help span {
- font-size: 80%;
- color: darkgreen;
- vertical-align:top;
- position: relative;
- top: -4px;
- padding: 0 2px;
-}
-
-/* Inputs */
-.openerp .oe_forms input[type="text"], .openerp .oe_forms input[type="password"], .openerp .oe_forms select, .openerp .oe_forms textarea {
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- -ms-box-sizing: border-box;
- box-sizing: border-box;
- padding: 0 2px 0 2px;
- border: 1px solid #999;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- border-radius: 3px;
- background: white;
- min-width: 90px;
- color: #1f1f1f;
-}
-.openerp .oe_forms textarea {
- resize:vertical;
-}
-.openerp .oe_forms input[type="text"], .openerp .oe_forms input[type="password"], .openerp .oe_forms select, .openerp .oe_forms .button {
- height: 22px;
-}
-.openerp .oe_forms input.field_datetime {
- min-width: 11em;
-}
-.openerp .oe_forms .button {
- color: #4c4c4c;
- white-space: nowrap;
-}
-.openerp .oe_forms .button span {
- position: relative;
- vertical-align: top;
-}
-.openerp img.ui-datepicker-trigger {
- margin-left: -20px;
- vertical-align: middle;
- cursor: pointer;
- position: relative;
- top: -1px;
-}
-.openerp img.oe_field_translate {
- margin-left: -21px;
- vertical-align: top;
- cursor: pointer;
- position: relative;
- top: 4px;
-}
-.openerp .oe_trad_field.touched {
- border: 1px solid green !important;
-}
-
-/* http://www.quirksmode.org/dom/inputfile.html
- * http://stackoverflow.com/questions/2855589/replace-input-type-file-by-an-image
- */
-.openerp .oe-binary-file-set {
- overflow: hidden;
- position: relative;
-}
-.openerp input.oe-binary-file {
- z-index: 2;
- line-height: 0;
- font-size: 50px;
- position: absolute;
- /* Should be adjusted for all browsers */
- top: -2px;
- left: -700px;
- opacity: 0;
- filter: alpha(opacity = 0);
- -ms-filter: "alpha(opacity=0)";
- margin: 0;
- padding:0;
-}
-
-/* Widgets */
-.openerp .separator {
- border: 0 solid #666;
-}
-.openerp .separator.horizontal {
- font-weight: bold;
- border-bottom-width: 1px;
- margin: 3px 4px 3px 1px;
- height: 15px;
-}
-.openerp .oe_form_frame_cell.oe_form_separator_vertical {
- border-left: 1px solid #666;
-}
-.openerp td.required input, .openerp td.required select {
- background-color: #D2D2FF !important;
-}
-.openerp td.invalid input, .openerp td.invalid select, .openerp td.invalid textarea {
- background-color: #F66 !important;
- border: 1px solid #D00 !important;
-}
-.openerp div.oe-progressbar span {
- position: absolute;
- margin-left: 10px;
- margin-top: 5px;
- font-weight: bold;
-}
-
-/* jQuery UI override */
-.openerp .ui-widget {
- font-size: 1em;
-}
-.openerp .oe_form_field_progressbar .ui-progressbar {
- height: 22px;
- font-size: 10px;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- -ms-box-sizing: border-box;
- box-sizing: border-box;
- border: 1px solid #999;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- border-radius: 3px;
- background: white;
- min-width: 90px;
-}
-
-/* Sidebar */
-.openerp .view-manager-main-table {
- margin: 0;
- width:100%;
- border-collapse:collapse;
- height:100%;
-}
-
-.openerp .view-manager-main-table tbody {
- vertical-align: top;
-}
-
-.openerp .view-manager-main-content {
- width: 100%;
- padding: 6px;
-}
-
-.openerp .view-manager-main-sidebar {
- width: 180px;
- padding: 0;
- margin: 0;
-}
-
-.openerp .sidebar-main-div {
- height: 100%;
- border-left: 1px solid #D2CFCF;
-}
-
-.openerp .sidebar-content {
- padding: 0;
- margin: 0;
- width: 180px;
- height: 100%;
- font-size: 0.9em;
-}
-
-.openerp .closed-sidebar .sidebar-content {
- width: 22px;
-}
-
-.openerp .closed-sidebar .sidebar-content {
- display: none;
-}
-
-.openerp .sidebar-main-div a {
- color: #555;
- text-decoration: none;
-}
-
-.openerp .sidebar-main-div a:hover {
- color: black;
-}
-
-.openerp .oe-sidebar-attachments-toolbar {
- margin: 4px 0 0 4px;
-}
-.openerp .oe-sidebar-attachments-items {
- clear: both;
- padding-top: 5px !important;
-}
-.openerp .oe-sidebar-attachments-items li {
- position: relative;
- padding: 0 0 3px 10px !important;
-}
-.openerp .oe-sidebar-attachments-items li:hover {
- background: #ddd;
-}
-.openerp .oe-sidebar-attachments-link {
- display: block;
- margin-right: 15px;
- overflow: hidden;
-}
-.openerp .oe-sidebar-attachment-delete {
- position: absolute;
- right: 2px;
- top: 1px;
- overflow: hidden;
- width: 15px;
- height: 15px;
- padding: 1px;
- border-radius: 7px;
- -moz-border-radius: 7px;
- -webkit-border-radius: 7px;
-}
-.openerp .oe-sidebar-attachment-delete:hover {
- background-color: white;
-}
-
-.openerp .view-manager-main-sidebar h2 {
- margin:0;
- font-size: 1.15em;
- color: #8E8E8E;
- text-shadow: white 0 1px 0;
- padding-left: 10px;
- padding-right: 21px;
- height: 21px;
-
- background: #ffffff; /* Old browsers */
- background: -moz-linear-gradient(top, #ffffff 0%, #ebe9e9 100%); /* FF3.6+ */
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#ebe9e9)); /* Chrome,Safari4+ */
- background: -webkit-linear-gradient(top, #ffffff 0%,#ebe9e9 100%); /* Chrome10+,Safari5.1+ */
- background: -o-linear-gradient(top, #ffffff 0%,#ebe9e9 100%); /* Opera11.10+ */
- background: -ms-linear-gradient(top, #ffffff 0%,#ebe9e9 100%); /* IE10+ */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFFFFF', endColorstr='#EBE9E9',GradientType=0 ); /* IE6-9 */
- background: linear-gradient(top, #ffffff 0%,#ebe9e9 100%); /* W3C */
-
- border: 1px solid #D2CFCF;
- border-right-width: 0;
- border-left-width: 0;
-}
-
-.openerp .view-manager-main-sidebar ul {
- list-style-type: none;
- margin: 0;
- padding: 0;
- display: block;
-}
-
-.openerp .view-manager-main-sidebar li {
- display: block;
- padding: 3px 3px 3px 10px;
-}
-
-.openerp .toggle-sidebar {
- cursor: pointer;
- border: 1px solid #D2CFCF;
- display: block;
- background: url(/base/static/src/img/toggle-a-bg.png);
- width: 21px;
- height: 21px;
- z-index: 10;
-}
-.openerp .open-sidebar .toggle-sidebar {
- margin-left: 158px;
- background-position: 21px 0;
- position: absolute;
-}
-.openerp .closed-sidebar .toggle-sidebar {
- border-left: none;
-}
-.openerp li.oe_sidebar_print {
- padding-left: 20px;
- background: 1px 3px url(/base/static/src/img/icons/gtk-print.png) no-repeat;
-}
-
-.openerp.kitten-mode-activated .main_table {
- background: url(http://placekitten.com/g/1500/800) repeat;
-}
-
-.openerp.kitten-mode-activated .header {
- background: url(http://placekitten.com/g/211/65) repeat;
-}
-
-.openerp.kitten-mode-activated .secondary_menu {
- background: url(http://placekitten.com/g/212/100) repeat;
-}
-
-.openerp.kitten-mode-activated .menu {
- background: #828282;
- background: -moz-linear-gradient(top, #828282 0%, #4D4D4D 100%);
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#828282), color-stop(100%,#4D4D4D));
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#828282', endColorstr='#4D4D4D',GradientType=0 );
-}
-.openerp.kitten-mode-activated .menu a {
- background: none;
-}
-.openerp.kitten-mode-activated .menu span {
- background: none;
-}
-.openerp.kitten-mode-activated .sidebar-content li a,
-.openerp.kitten-mode-activated .oe-application .view-manager-main-content h2.oe_view_title,
-.openerp.kitten-mode-activated .oe-application .view-manager-main-content a.searchview_group_string,
-.openerp.kitten-mode-activated .oe-application .view-manager-main-content label {
- color: white;
-}
-.openerp.kitten-mode-activated .menu,
-.openerp.kitten-mode-activated .header_corner,
-.openerp.kitten-mode-activated .header_title,
-.openerp.kitten-mode-activated .secondary_menu div,
-.openerp.kitten-mode-activated .oe-application,
-.openerp.kitten-mode-activated .oe_footer,
-.openerp.kitten-mode-activated .loading,
-.openerp.kitten-mode-activated .ui-dialog {
- opacity:0.8;
- filter:alpha(opacity=80);
-}
-.openerp.kitten-mode-activated .header .company_logo {
- background: url(http://placekitten.com/g/180/46);
-}
-.openerp.kitten-mode-activated .loading {
- background: #828282;
- border-color: #828282;
-}
-
-.openerp .oe-m2o {
- padding-right: 20px;
- white-space: nowrap;
-}
-.openerp .oe_forms .oe-m2o input[type="text"] {
- padding-right: 20px;
-}
-.openerp .oe-m2o-drop-down-button {
- margin-left: -23px;
-}
-.openerp .oe-m2o-drop-down-button img,
-.openerp .oe-m2o-cm-button img {
- margin-bottom: -4px;
- cursor: pointer;
-}
-.openerp .oe-m2o-cm-button img {
- margin-left: 4px;
-}
-.openerp .oe-m2o-disabled-cm {
- color: grey;
-}
-.parent_top {
- vertical-align: text-top;
-}
-
-.openerp .oe-dialog-warning p {
- padding-left: 1em;
- font-size: 1.2em;
- font-weight: bold;
-}
-
-.openerp .dhx_mini_calendar {
- -moz-box-shadow: none;
- -khtml-box-shadow: none;
- -webkit-box-shadow: none;
- box-shadow: none;
-}
-.openerp .oe-treeview-table {
- width: 100%;
-}
-.treeview-tr, .treeview-td {
- cursor: pointer;
- vertical-align: top;
- text-align: left;
-}
-.treeview-tr span, .treeview-td span {
- display: block;
-}
-.treeview-tr:first-of-type {
- background: transparent url(/base/static/src/img/expand.gif) 0 50% no-repeat;
-}
-.oe-open .treeview-tr:first-of-type {
- background-image: url(/base/static/src/img/collapse.gif);
-}
-.treeview-tr:first-of-type span,
-.treeview-td:first-of-type span {
- margin-left: 16px;
-}
-
-.treeview-header {
- text-align: left;
- vertical-align: top;
-}
-/* Shortcuts*/
-.oe-shortcut-toggle {
- height: 20px;
- padding: 0;
- width: 24px;
- cursor: pointer;
- display: block;
- background: url(/base/static/src/img/add-shortcut.png) no-repeat bottom;
- float: left;
-}
-.oe-shortcut-remove{
- background: url(/base/static/src/img/remove-shortcut.png) no-repeat bottom;
-}
-/* ================ */
-.oe-shortcuts {
- position: absolute;
-
- margin: 0;
- padding: 6px 5px;
- top: 37px;
- left: 197px;
- right: 0;
- height: 17px;
- line-height: 1.2;
-}
-.oe-shortcuts ul {
- display: block;
- overflow: hidden;
- list-style: none;
- white-space: nowrap;
- padding: 0;
- margin: 0;
-}
-.oe-shortcuts li {
- cursor: pointer;
- display: -moz-inline-stack;
- display: inline-block;
- display: inline; /*IE7 */
- color: #fff;
- text-align: center;
- border-left: 1px solid #909090;
- padding: 4px;
- font-size: 90%;
- font-weight: normal;
-}
-.oe-shortcuts li:first-child {
- border-left: none;
- padding-left: 0;
-}
diff --git a/addons/base/static/src/css/data_export.css b/addons/base/static/src/css/data_export.css
deleted file mode 100644
index 7b4b9707b39..00000000000
--- a/addons/base/static/src/css/data_export.css
+++ /dev/null
@@ -1,85 +0,0 @@
-.openerp .oe_export_row tr{
- background-color: #FFFFFF;
- font-size: 0.8em;
- height: 22px;
-}
-
-.openerp tr.ui-selected td {
- background-color: #CCCCCC;
-}
-
-.openerp .oe_export_requiredfield {
- background-color: #D2D2FF;
-}
-
-.openerp .oe_export_readonlyfield{
- background-color: #999999;
-}
-
-.openerp .oe_export_row:hover{
- background-color: #F3F3F3;
-}
-
-.openerp .oe_export_fields_selector_export {
- width: 100%;
- height: 400px;
-}
-
-.openerp .oe_export_fields_selector_left {
- width: 50%;
-}
-
-.openerp div#left_field_panel {
- overflow: scroll;
- width: 100%;
- height: 400px;
- border: solid #999999 1px;
-}
-
-.openerp .oe_export_fields_selector_center {
- width: 102px;
-}
-
-.openerp .oe_export_fields_selector_right {
- width: 45%;
- height: 400px;
-}
-
-.openerp .oe_export_fields_selector_export select{
- width: 100%;
- height: 100%;
-}
-
-.openerp .oe_export_tree_header{
- border: 0.5px solid #E3E3E3;
- text-align: left;
- white-space: nowrap;
- padding: 4px 5px;
- background: url(/base/static/src/img/header.gif);
-}
-
-
-.openerp table.tree_grid{
- border: 1px solid #E3E3E3;
- text-align: left;
- white-space: nowrap;
- background-color:#E3E3E3;
- border-collapse: collapse;
- width: 100%;
-}
-
-.openerp table.tree_grid a:hover {
- color: blue;
- border: none;
-}
-
-.openerp table.tree_grid a {
- color: #5F5C5C;
- border: none;
- display: block;
-}
-
-.openerp .oe_export_button_export {
- border: 1px solid #006;
- background-color: #F3F3F3;
-}
diff --git a/addons/base/static/src/img/accessories-archiver.png b/addons/base/static/src/img/accessories-archiver.png
deleted file mode 100644
index 8bcbe4566bc..00000000000
--- a/addons/base/static/src/img/accessories-archiver.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/add-shortcut.png b/addons/base/static/src/img/add-shortcut.png
deleted file mode 100644
index bcc0a09eb45..00000000000
--- a/addons/base/static/src/img/add-shortcut.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/attachments-close.png b/addons/base/static/src/img/attachments-close.png
deleted file mode 100644
index 14d645534b8..00000000000
--- a/addons/base/static/src/img/attachments-close.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/collapse.gif b/addons/base/static/src/img/collapse.gif
deleted file mode 100644
index 759e72ebcfe..00000000000
--- a/addons/base/static/src/img/collapse.gif
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/db.png b/addons/base/static/src/img/db.png
deleted file mode 100644
index 83e42df26b3..00000000000
--- a/addons/base/static/src/img/db.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/down-arrow.png b/addons/base/static/src/img/down-arrow.png
deleted file mode 100644
index b1288e52682..00000000000
--- a/addons/base/static/src/img/down-arrow.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/expand.gif b/addons/base/static/src/img/expand.gif
deleted file mode 100644
index ca98d0b5f2b..00000000000
--- a/addons/base/static/src/img/expand.gif
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/favicon.ico b/addons/base/static/src/img/favicon.ico
deleted file mode 100644
index a323cc21c00..00000000000
--- a/addons/base/static/src/img/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/header-about.png b/addons/base/static/src/img/header-about.png
deleted file mode 100644
index b53e9a86ebe..00000000000
--- a/addons/base/static/src/img/header-about.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/header-background.png b/addons/base/static/src/img/header-background.png
deleted file mode 100644
index 774b3954124..00000000000
--- a/addons/base/static/src/img/header-background.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/header-help.png b/addons/base/static/src/img/header-help.png
deleted file mode 100644
index 19e9906fdef..00000000000
--- a/addons/base/static/src/img/header-help.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/header-home.png b/addons/base/static/src/img/header-home.png
deleted file mode 100644
index fd96742d15a..00000000000
--- a/addons/base/static/src/img/header-home.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/header-preferences.png b/addons/base/static/src/img/header-preferences.png
deleted file mode 100644
index 6c978b49f55..00000000000
--- a/addons/base/static/src/img/header-preferences.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/header-requests.png b/addons/base/static/src/img/header-requests.png
deleted file mode 100644
index 6577e7e6448..00000000000
--- a/addons/base/static/src/img/header-requests.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/header.gif b/addons/base/static/src/img/header.gif
deleted file mode 100644
index f40bd9c0f6a..00000000000
--- a/addons/base/static/src/img/header.gif
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_ABOUT.png b/addons/base/static/src/img/icons/STOCK_ABOUT.png
deleted file mode 100644
index 1b430a35758..00000000000
--- a/addons/base/static/src/img/icons/STOCK_ABOUT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_ADD.png b/addons/base/static/src/img/icons/STOCK_ADD.png
deleted file mode 100644
index 70612c181c6..00000000000
--- a/addons/base/static/src/img/icons/STOCK_ADD.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_APPLY.png b/addons/base/static/src/img/icons/STOCK_APPLY.png
deleted file mode 100644
index 116f2e433bb..00000000000
--- a/addons/base/static/src/img/icons/STOCK_APPLY.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_BOLD.png b/addons/base/static/src/img/icons/STOCK_BOLD.png
deleted file mode 100644
index 408f25aa20b..00000000000
--- a/addons/base/static/src/img/icons/STOCK_BOLD.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_CANCEL.png b/addons/base/static/src/img/icons/STOCK_CANCEL.png
deleted file mode 100644
index 8cf6273281b..00000000000
--- a/addons/base/static/src/img/icons/STOCK_CANCEL.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_CDROM.png b/addons/base/static/src/img/icons/STOCK_CDROM.png
deleted file mode 100644
index 27e8edd8a0b..00000000000
--- a/addons/base/static/src/img/icons/STOCK_CDROM.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_CLEAR.png b/addons/base/static/src/img/icons/STOCK_CLEAR.png
deleted file mode 100644
index b2874fb84fa..00000000000
--- a/addons/base/static/src/img/icons/STOCK_CLEAR.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_CLOSE.png b/addons/base/static/src/img/icons/STOCK_CLOSE.png
deleted file mode 100644
index 4966974e178..00000000000
--- a/addons/base/static/src/img/icons/STOCK_CLOSE.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_COLOR_PICKER.png b/addons/base/static/src/img/icons/STOCK_COLOR_PICKER.png
deleted file mode 100644
index 232d54f8f3b..00000000000
--- a/addons/base/static/src/img/icons/STOCK_COLOR_PICKER.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_CONNECT.png b/addons/base/static/src/img/icons/STOCK_CONNECT.png
deleted file mode 100644
index c820b54abcc..00000000000
--- a/addons/base/static/src/img/icons/STOCK_CONNECT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_CONVERT.png b/addons/base/static/src/img/icons/STOCK_CONVERT.png
deleted file mode 100644
index 6288b964cc0..00000000000
--- a/addons/base/static/src/img/icons/STOCK_CONVERT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_COPY.png b/addons/base/static/src/img/icons/STOCK_COPY.png
deleted file mode 100644
index 3d68da606d2..00000000000
--- a/addons/base/static/src/img/icons/STOCK_COPY.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_CUT.png b/addons/base/static/src/img/icons/STOCK_CUT.png
deleted file mode 100644
index 96681d26968..00000000000
--- a/addons/base/static/src/img/icons/STOCK_CUT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_DELETE.png b/addons/base/static/src/img/icons/STOCK_DELETE.png
deleted file mode 100644
index 879d6fd1cbe..00000000000
--- a/addons/base/static/src/img/icons/STOCK_DELETE.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_DIALOG_AUTHENTICATION.png b/addons/base/static/src/img/icons/STOCK_DIALOG_AUTHENTICATION.png
deleted file mode 100644
index eb411112f83..00000000000
--- a/addons/base/static/src/img/icons/STOCK_DIALOG_AUTHENTICATION.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_DIALOG_ERROR.png b/addons/base/static/src/img/icons/STOCK_DIALOG_ERROR.png
deleted file mode 100644
index e97bc43504b..00000000000
--- a/addons/base/static/src/img/icons/STOCK_DIALOG_ERROR.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_DIALOG_INFO.png b/addons/base/static/src/img/icons/STOCK_DIALOG_INFO.png
deleted file mode 100644
index ed46c3ecdb3..00000000000
--- a/addons/base/static/src/img/icons/STOCK_DIALOG_INFO.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_DIALOG_QUESTION.png b/addons/base/static/src/img/icons/STOCK_DIALOG_QUESTION.png
deleted file mode 100644
index ef68f43f43f..00000000000
--- a/addons/base/static/src/img/icons/STOCK_DIALOG_QUESTION.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_DIALOG_WARNING.png b/addons/base/static/src/img/icons/STOCK_DIALOG_WARNING.png
deleted file mode 100644
index 65a4d2c7220..00000000000
--- a/addons/base/static/src/img/icons/STOCK_DIALOG_WARNING.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_DIRECTORY.png b/addons/base/static/src/img/icons/STOCK_DIRECTORY.png
deleted file mode 100644
index 8e41b7878a9..00000000000
--- a/addons/base/static/src/img/icons/STOCK_DIRECTORY.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_DISCONNECT.png b/addons/base/static/src/img/icons/STOCK_DISCONNECT.png
deleted file mode 100644
index fd188701fc2..00000000000
--- a/addons/base/static/src/img/icons/STOCK_DISCONNECT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_DND.png b/addons/base/static/src/img/icons/STOCK_DND.png
deleted file mode 100644
index bf3b8068397..00000000000
--- a/addons/base/static/src/img/icons/STOCK_DND.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_DND_MULTIPLE.png b/addons/base/static/src/img/icons/STOCK_DND_MULTIPLE.png
deleted file mode 100644
index aa4c65ad5b1..00000000000
--- a/addons/base/static/src/img/icons/STOCK_DND_MULTIPLE.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_EDIT.png b/addons/base/static/src/img/icons/STOCK_EDIT.png
deleted file mode 100644
index 53b7d0855ed..00000000000
--- a/addons/base/static/src/img/icons/STOCK_EDIT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_EXECUTE.png b/addons/base/static/src/img/icons/STOCK_EXECUTE.png
deleted file mode 100644
index eddc0f86b25..00000000000
--- a/addons/base/static/src/img/icons/STOCK_EXECUTE.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_FILE.png b/addons/base/static/src/img/icons/STOCK_FILE.png
deleted file mode 100644
index fa157156bcc..00000000000
--- a/addons/base/static/src/img/icons/STOCK_FILE.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_FIND.png b/addons/base/static/src/img/icons/STOCK_FIND.png
deleted file mode 100644
index 7a23b0125b5..00000000000
--- a/addons/base/static/src/img/icons/STOCK_FIND.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_FIND_AND_REPLACE.png b/addons/base/static/src/img/icons/STOCK_FIND_AND_REPLACE.png
deleted file mode 100644
index b8d8eeec1b2..00000000000
--- a/addons/base/static/src/img/icons/STOCK_FIND_AND_REPLACE.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_FLOPPY.png b/addons/base/static/src/img/icons/STOCK_FLOPPY.png
deleted file mode 100644
index 7d8209cfb6f..00000000000
--- a/addons/base/static/src/img/icons/STOCK_FLOPPY.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_FULLSCREEN.png b/addons/base/static/src/img/icons/STOCK_FULLSCREEN.png
deleted file mode 100644
index 8ddc31e7481..00000000000
--- a/addons/base/static/src/img/icons/STOCK_FULLSCREEN.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_GOTO_BOTTOM.png b/addons/base/static/src/img/icons/STOCK_GOTO_BOTTOM.png
deleted file mode 100644
index be52840dee1..00000000000
--- a/addons/base/static/src/img/icons/STOCK_GOTO_BOTTOM.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_GOTO_FIRST.png b/addons/base/static/src/img/icons/STOCK_GOTO_FIRST.png
deleted file mode 100644
index 3d00e36d696..00000000000
--- a/addons/base/static/src/img/icons/STOCK_GOTO_FIRST.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_GOTO_LAST.png b/addons/base/static/src/img/icons/STOCK_GOTO_LAST.png
deleted file mode 100644
index 2028226996d..00000000000
--- a/addons/base/static/src/img/icons/STOCK_GOTO_LAST.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_GOTO_TOP.png b/addons/base/static/src/img/icons/STOCK_GOTO_TOP.png
deleted file mode 100644
index 227a91e5157..00000000000
--- a/addons/base/static/src/img/icons/STOCK_GOTO_TOP.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_GO_BACK.png b/addons/base/static/src/img/icons/STOCK_GO_BACK.png
deleted file mode 100644
index 568117dc170..00000000000
--- a/addons/base/static/src/img/icons/STOCK_GO_BACK.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_GO_DOWN.png b/addons/base/static/src/img/icons/STOCK_GO_DOWN.png
deleted file mode 100644
index 5677cffe6a3..00000000000
--- a/addons/base/static/src/img/icons/STOCK_GO_DOWN.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_GO_FORWARD.png b/addons/base/static/src/img/icons/STOCK_GO_FORWARD.png
deleted file mode 100644
index fa89d31b734..00000000000
--- a/addons/base/static/src/img/icons/STOCK_GO_FORWARD.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_GO_UP.png b/addons/base/static/src/img/icons/STOCK_GO_UP.png
deleted file mode 100644
index 84f96fdfca2..00000000000
--- a/addons/base/static/src/img/icons/STOCK_GO_UP.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_HARDDISK.png b/addons/base/static/src/img/icons/STOCK_HARDDISK.png
deleted file mode 100644
index 73e5ef0a82e..00000000000
--- a/addons/base/static/src/img/icons/STOCK_HARDDISK.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_HELP.png b/addons/base/static/src/img/icons/STOCK_HELP.png
deleted file mode 100644
index f8e17009dd6..00000000000
--- a/addons/base/static/src/img/icons/STOCK_HELP.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_HOME.png b/addons/base/static/src/img/icons/STOCK_HOME.png
deleted file mode 100644
index 9d3d50d0fcb..00000000000
--- a/addons/base/static/src/img/icons/STOCK_HOME.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_INDENT.png b/addons/base/static/src/img/icons/STOCK_INDENT.png
deleted file mode 100644
index 19f2669447d..00000000000
--- a/addons/base/static/src/img/icons/STOCK_INDENT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_INDEX.png b/addons/base/static/src/img/icons/STOCK_INDEX.png
deleted file mode 100644
index 0b63cc25fa8..00000000000
--- a/addons/base/static/src/img/icons/STOCK_INDEX.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_INFO.png b/addons/base/static/src/img/icons/STOCK_INFO.png
deleted file mode 100644
index 272019f5c99..00000000000
--- a/addons/base/static/src/img/icons/STOCK_INFO.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_ITALIC.png b/addons/base/static/src/img/icons/STOCK_ITALIC.png
deleted file mode 100644
index 26c57226a31..00000000000
--- a/addons/base/static/src/img/icons/STOCK_ITALIC.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_JUMP_TO.png b/addons/base/static/src/img/icons/STOCK_JUMP_TO.png
deleted file mode 100644
index 82d7896bdac..00000000000
--- a/addons/base/static/src/img/icons/STOCK_JUMP_TO.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_JUSTIFY_CENTER.png b/addons/base/static/src/img/icons/STOCK_JUSTIFY_CENTER.png
deleted file mode 100644
index d5f514298eb..00000000000
--- a/addons/base/static/src/img/icons/STOCK_JUSTIFY_CENTER.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_JUSTIFY_FILL.png b/addons/base/static/src/img/icons/STOCK_JUSTIFY_FILL.png
deleted file mode 100644
index 5e2f5c73f30..00000000000
--- a/addons/base/static/src/img/icons/STOCK_JUSTIFY_FILL.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_JUSTIFY_LEFT.png b/addons/base/static/src/img/icons/STOCK_JUSTIFY_LEFT.png
deleted file mode 100644
index ecb76b117eb..00000000000
--- a/addons/base/static/src/img/icons/STOCK_JUSTIFY_LEFT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_JUSTIFY_RIGHT.png b/addons/base/static/src/img/icons/STOCK_JUSTIFY_RIGHT.png
deleted file mode 100644
index 3cd4d161420..00000000000
--- a/addons/base/static/src/img/icons/STOCK_JUSTIFY_RIGHT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_LEAVE_FULLSCREEN.png b/addons/base/static/src/img/icons/STOCK_LEAVE_FULLSCREEN.png
deleted file mode 100644
index 15bc8ab7d7b..00000000000
--- a/addons/base/static/src/img/icons/STOCK_LEAVE_FULLSCREEN.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_MEDIA_FORWARD.png b/addons/base/static/src/img/icons/STOCK_MEDIA_FORWARD.png
deleted file mode 100644
index e5e198fbb79..00000000000
--- a/addons/base/static/src/img/icons/STOCK_MEDIA_FORWARD.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_MEDIA_NEXT.png b/addons/base/static/src/img/icons/STOCK_MEDIA_NEXT.png
deleted file mode 100644
index e0aa2431cf0..00000000000
--- a/addons/base/static/src/img/icons/STOCK_MEDIA_NEXT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_MEDIA_PAUSE.png b/addons/base/static/src/img/icons/STOCK_MEDIA_PAUSE.png
deleted file mode 100644
index 6721994eb8d..00000000000
--- a/addons/base/static/src/img/icons/STOCK_MEDIA_PAUSE.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_MEDIA_PLAY.png b/addons/base/static/src/img/icons/STOCK_MEDIA_PLAY.png
deleted file mode 100644
index b0832712c81..00000000000
--- a/addons/base/static/src/img/icons/STOCK_MEDIA_PLAY.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_MEDIA_PREVIOUS.png b/addons/base/static/src/img/icons/STOCK_MEDIA_PREVIOUS.png
deleted file mode 100644
index 756899e0bc1..00000000000
--- a/addons/base/static/src/img/icons/STOCK_MEDIA_PREVIOUS.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_MEDIA_RECORD.png b/addons/base/static/src/img/icons/STOCK_MEDIA_RECORD.png
deleted file mode 100644
index 904974c81e5..00000000000
--- a/addons/base/static/src/img/icons/STOCK_MEDIA_RECORD.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_MEDIA_REWIND.png b/addons/base/static/src/img/icons/STOCK_MEDIA_REWIND.png
deleted file mode 100644
index 9c22d9e2778..00000000000
--- a/addons/base/static/src/img/icons/STOCK_MEDIA_REWIND.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_MEDIA_STOP.png b/addons/base/static/src/img/icons/STOCK_MEDIA_STOP.png
deleted file mode 100644
index 128cc2313ec..00000000000
--- a/addons/base/static/src/img/icons/STOCK_MEDIA_STOP.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_MISSING_IMAGE.png b/addons/base/static/src/img/icons/STOCK_MISSING_IMAGE.png
deleted file mode 100644
index cc69ed33e4b..00000000000
--- a/addons/base/static/src/img/icons/STOCK_MISSING_IMAGE.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_NETWORK.png b/addons/base/static/src/img/icons/STOCK_NETWORK.png
deleted file mode 100644
index df94a515fec..00000000000
--- a/addons/base/static/src/img/icons/STOCK_NETWORK.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_NEW.png b/addons/base/static/src/img/icons/STOCK_NEW.png
deleted file mode 100644
index 04a290fac7d..00000000000
--- a/addons/base/static/src/img/icons/STOCK_NEW.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_NO.png b/addons/base/static/src/img/icons/STOCK_NO.png
deleted file mode 100644
index 047ddcd9289..00000000000
--- a/addons/base/static/src/img/icons/STOCK_NO.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_OK.png b/addons/base/static/src/img/icons/STOCK_OK.png
deleted file mode 100644
index 7755b8769f0..00000000000
--- a/addons/base/static/src/img/icons/STOCK_OK.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_OPEN.png b/addons/base/static/src/img/icons/STOCK_OPEN.png
deleted file mode 100644
index 9cdd8c66770..00000000000
--- a/addons/base/static/src/img/icons/STOCK_OPEN.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_PASTE.png b/addons/base/static/src/img/icons/STOCK_PASTE.png
deleted file mode 100644
index 840f26c8b38..00000000000
--- a/addons/base/static/src/img/icons/STOCK_PASTE.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_PREFERENCES.png b/addons/base/static/src/img/icons/STOCK_PREFERENCES.png
deleted file mode 100644
index 9ba17a0ab20..00000000000
--- a/addons/base/static/src/img/icons/STOCK_PREFERENCES.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_PRINT.png b/addons/base/static/src/img/icons/STOCK_PRINT.png
deleted file mode 100644
index be0ed4efb44..00000000000
--- a/addons/base/static/src/img/icons/STOCK_PRINT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_PRINT_PREVIEW.png b/addons/base/static/src/img/icons/STOCK_PRINT_PREVIEW.png
deleted file mode 100644
index ab15fcbd307..00000000000
--- a/addons/base/static/src/img/icons/STOCK_PRINT_PREVIEW.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_PROPERTIES.png b/addons/base/static/src/img/icons/STOCK_PROPERTIES.png
deleted file mode 100644
index 894415ec1ce..00000000000
--- a/addons/base/static/src/img/icons/STOCK_PROPERTIES.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_QUIT.png b/addons/base/static/src/img/icons/STOCK_QUIT.png
deleted file mode 100644
index 50b5144660b..00000000000
--- a/addons/base/static/src/img/icons/STOCK_QUIT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_REDO.png b/addons/base/static/src/img/icons/STOCK_REDO.png
deleted file mode 100644
index 54055b3966d..00000000000
--- a/addons/base/static/src/img/icons/STOCK_REDO.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_REFRESH.png b/addons/base/static/src/img/icons/STOCK_REFRESH.png
deleted file mode 100644
index 7474728b4c0..00000000000
--- a/addons/base/static/src/img/icons/STOCK_REFRESH.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_REMOVE.png b/addons/base/static/src/img/icons/STOCK_REMOVE.png
deleted file mode 100644
index c2b6e915f77..00000000000
--- a/addons/base/static/src/img/icons/STOCK_REMOVE.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_REVERT_TO_SAVED.png b/addons/base/static/src/img/icons/STOCK_REVERT_TO_SAVED.png
deleted file mode 100644
index eaf54584edf..00000000000
--- a/addons/base/static/src/img/icons/STOCK_REVERT_TO_SAVED.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_SAVE.png b/addons/base/static/src/img/icons/STOCK_SAVE.png
deleted file mode 100644
index c61836548a7..00000000000
--- a/addons/base/static/src/img/icons/STOCK_SAVE.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_SAVE_AS.png b/addons/base/static/src/img/icons/STOCK_SAVE_AS.png
deleted file mode 100644
index 1831e4e0a4b..00000000000
--- a/addons/base/static/src/img/icons/STOCK_SAVE_AS.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_SELECT_COLOR.png b/addons/base/static/src/img/icons/STOCK_SELECT_COLOR.png
deleted file mode 100644
index 12b015df107..00000000000
--- a/addons/base/static/src/img/icons/STOCK_SELECT_COLOR.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_SELECT_FONT.png b/addons/base/static/src/img/icons/STOCK_SELECT_FONT.png
deleted file mode 100644
index 66e606313a5..00000000000
--- a/addons/base/static/src/img/icons/STOCK_SELECT_FONT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_SORT_ASCENDING.png b/addons/base/static/src/img/icons/STOCK_SORT_ASCENDING.png
deleted file mode 100644
index a648fa0d359..00000000000
--- a/addons/base/static/src/img/icons/STOCK_SORT_ASCENDING.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_SORT_DESCENDING.png b/addons/base/static/src/img/icons/STOCK_SORT_DESCENDING.png
deleted file mode 100644
index a90b588d797..00000000000
--- a/addons/base/static/src/img/icons/STOCK_SORT_DESCENDING.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_SPELL_CHECK.png b/addons/base/static/src/img/icons/STOCK_SPELL_CHECK.png
deleted file mode 100644
index 698f7c24a43..00000000000
--- a/addons/base/static/src/img/icons/STOCK_SPELL_CHECK.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_STOP.png b/addons/base/static/src/img/icons/STOCK_STOP.png
deleted file mode 100644
index 2ee93ed6415..00000000000
--- a/addons/base/static/src/img/icons/STOCK_STOP.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_STRIKETHROUGH.png b/addons/base/static/src/img/icons/STOCK_STRIKETHROUGH.png
deleted file mode 100644
index 1c11f214622..00000000000
--- a/addons/base/static/src/img/icons/STOCK_STRIKETHROUGH.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_UNDELETE.png b/addons/base/static/src/img/icons/STOCK_UNDELETE.png
deleted file mode 100644
index c44b940c03b..00000000000
--- a/addons/base/static/src/img/icons/STOCK_UNDELETE.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_UNDERLINE.png b/addons/base/static/src/img/icons/STOCK_UNDERLINE.png
deleted file mode 100644
index 7dbb5d7e60a..00000000000
--- a/addons/base/static/src/img/icons/STOCK_UNDERLINE.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_UNDO.png b/addons/base/static/src/img/icons/STOCK_UNDO.png
deleted file mode 100644
index 7a50de0c61e..00000000000
--- a/addons/base/static/src/img/icons/STOCK_UNDO.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_UNINDENT.png b/addons/base/static/src/img/icons/STOCK_UNINDENT.png
deleted file mode 100644
index 8ace914c1bd..00000000000
--- a/addons/base/static/src/img/icons/STOCK_UNINDENT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_YES.png b/addons/base/static/src/img/icons/STOCK_YES.png
deleted file mode 100644
index 01fb373c251..00000000000
--- a/addons/base/static/src/img/icons/STOCK_YES.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_ZOOM_100.png b/addons/base/static/src/img/icons/STOCK_ZOOM_100.png
deleted file mode 100644
index 5193406b787..00000000000
--- a/addons/base/static/src/img/icons/STOCK_ZOOM_100.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_ZOOM_FIT.png b/addons/base/static/src/img/icons/STOCK_ZOOM_FIT.png
deleted file mode 100644
index 1e70e619466..00000000000
--- a/addons/base/static/src/img/icons/STOCK_ZOOM_FIT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_ZOOM_IN.png b/addons/base/static/src/img/icons/STOCK_ZOOM_IN.png
deleted file mode 100644
index 29e50e45d4a..00000000000
--- a/addons/base/static/src/img/icons/STOCK_ZOOM_IN.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/STOCK_ZOOM_OUT.png b/addons/base/static/src/img/icons/STOCK_ZOOM_OUT.png
deleted file mode 100644
index 0da5ee7ec13..00000000000
--- a/addons/base/static/src/img/icons/STOCK_ZOOM_OUT.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-add.png b/addons/base/static/src/img/icons/gtk-add.png
deleted file mode 100644
index 70612c181c6..00000000000
--- a/addons/base/static/src/img/icons/gtk-add.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-apply.png b/addons/base/static/src/img/icons/gtk-apply.png
deleted file mode 100644
index 116f2e433bb..00000000000
--- a/addons/base/static/src/img/icons/gtk-apply.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-cancel.png b/addons/base/static/src/img/icons/gtk-cancel.png
deleted file mode 100644
index 8cf6273281b..00000000000
--- a/addons/base/static/src/img/icons/gtk-cancel.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-close.png b/addons/base/static/src/img/icons/gtk-close.png
deleted file mode 100644
index 4966974e178..00000000000
--- a/addons/base/static/src/img/icons/gtk-close.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-convert.png b/addons/base/static/src/img/icons/gtk-convert.png
deleted file mode 100644
index 6288b964cc0..00000000000
--- a/addons/base/static/src/img/icons/gtk-convert.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-delete.png b/addons/base/static/src/img/icons/gtk-delete.png
deleted file mode 100644
index 879d6fd1cbe..00000000000
--- a/addons/base/static/src/img/icons/gtk-delete.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-dnd.png b/addons/base/static/src/img/icons/gtk-dnd.png
deleted file mode 100644
index bf3b8068397..00000000000
--- a/addons/base/static/src/img/icons/gtk-dnd.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-edit.png b/addons/base/static/src/img/icons/gtk-edit.png
deleted file mode 100644
index 53b7d0855ed..00000000000
--- a/addons/base/static/src/img/icons/gtk-edit.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-execute.png b/addons/base/static/src/img/icons/gtk-execute.png
deleted file mode 100644
index eddc0f86b25..00000000000
--- a/addons/base/static/src/img/icons/gtk-execute.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-find.png b/addons/base/static/src/img/icons/gtk-find.png
deleted file mode 100644
index 7a23b0125b5..00000000000
--- a/addons/base/static/src/img/icons/gtk-find.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-go-back.png b/addons/base/static/src/img/icons/gtk-go-back.png
deleted file mode 100644
index 568117dc170..00000000000
--- a/addons/base/static/src/img/icons/gtk-go-back.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-go-down.png b/addons/base/static/src/img/icons/gtk-go-down.png
deleted file mode 100644
index 5677cffe6a3..00000000000
--- a/addons/base/static/src/img/icons/gtk-go-down.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-go-forward.png b/addons/base/static/src/img/icons/gtk-go-forward.png
deleted file mode 100644
index fa89d31b734..00000000000
--- a/addons/base/static/src/img/icons/gtk-go-forward.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-go-up.png b/addons/base/static/src/img/icons/gtk-go-up.png
deleted file mode 100644
index 84f96fdfca2..00000000000
--- a/addons/base/static/src/img/icons/gtk-go-up.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-goto-last.png b/addons/base/static/src/img/icons/gtk-goto-last.png
deleted file mode 100644
index 2028226996d..00000000000
--- a/addons/base/static/src/img/icons/gtk-goto-last.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-indent.png b/addons/base/static/src/img/icons/gtk-indent.png
deleted file mode 100644
index 19f2669447d..00000000000
--- a/addons/base/static/src/img/icons/gtk-indent.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-index.png b/addons/base/static/src/img/icons/gtk-index.png
deleted file mode 100644
index 0b63cc25fa8..00000000000
--- a/addons/base/static/src/img/icons/gtk-index.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-jump-to.png b/addons/base/static/src/img/icons/gtk-jump-to.png
deleted file mode 100644
index 82d7896bdac..00000000000
--- a/addons/base/static/src/img/icons/gtk-jump-to.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-justify-fill.png b/addons/base/static/src/img/icons/gtk-justify-fill.png
deleted file mode 100644
index 5e2f5c73f30..00000000000
--- a/addons/base/static/src/img/icons/gtk-justify-fill.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-media-pause.png b/addons/base/static/src/img/icons/gtk-media-pause.png
deleted file mode 100644
index 6721994eb8d..00000000000
--- a/addons/base/static/src/img/icons/gtk-media-pause.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-media-play.png b/addons/base/static/src/img/icons/gtk-media-play.png
deleted file mode 100644
index b0832712c81..00000000000
--- a/addons/base/static/src/img/icons/gtk-media-play.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-network.png b/addons/base/static/src/img/icons/gtk-network.png
deleted file mode 100644
index df94a515fec..00000000000
--- a/addons/base/static/src/img/icons/gtk-network.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-new.png b/addons/base/static/src/img/icons/gtk-new.png
deleted file mode 100644
index 04a290fac7d..00000000000
--- a/addons/base/static/src/img/icons/gtk-new.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-no.png b/addons/base/static/src/img/icons/gtk-no.png
deleted file mode 100644
index 047ddcd9289..00000000000
--- a/addons/base/static/src/img/icons/gtk-no.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-ok.png b/addons/base/static/src/img/icons/gtk-ok.png
deleted file mode 100644
index 7755b8769f0..00000000000
--- a/addons/base/static/src/img/icons/gtk-ok.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-open.png b/addons/base/static/src/img/icons/gtk-open.png
deleted file mode 100644
index 9cdd8c66770..00000000000
--- a/addons/base/static/src/img/icons/gtk-open.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-print.png b/addons/base/static/src/img/icons/gtk-print.png
deleted file mode 100644
index be0ed4efb44..00000000000
--- a/addons/base/static/src/img/icons/gtk-print.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-redo.png b/addons/base/static/src/img/icons/gtk-redo.png
deleted file mode 100644
index 54055b3966d..00000000000
--- a/addons/base/static/src/img/icons/gtk-redo.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-remove.png b/addons/base/static/src/img/icons/gtk-remove.png
deleted file mode 100644
index c2b6e915f77..00000000000
--- a/addons/base/static/src/img/icons/gtk-remove.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-save.png b/addons/base/static/src/img/icons/gtk-save.png
deleted file mode 100644
index c61836548a7..00000000000
--- a/addons/base/static/src/img/icons/gtk-save.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-sort-descending.png b/addons/base/static/src/img/icons/gtk-sort-descending.png
deleted file mode 100644
index a90b588d797..00000000000
--- a/addons/base/static/src/img/icons/gtk-sort-descending.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-stop.png b/addons/base/static/src/img/icons/gtk-stop.png
deleted file mode 100644
index 2ee93ed6415..00000000000
--- a/addons/base/static/src/img/icons/gtk-stop.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-undo.png b/addons/base/static/src/img/icons/gtk-undo.png
deleted file mode 100644
index 7a50de0c61e..00000000000
--- a/addons/base/static/src/img/icons/gtk-undo.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-yes.png b/addons/base/static/src/img/icons/gtk-yes.png
deleted file mode 100644
index 01fb373c251..00000000000
--- a/addons/base/static/src/img/icons/gtk-yes.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-zoom-fit.png b/addons/base/static/src/img/icons/gtk-zoom-fit.png
deleted file mode 100644
index 1e70e619466..00000000000
--- a/addons/base/static/src/img/icons/gtk-zoom-fit.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/gtk-zoom-in.png b/addons/base/static/src/img/icons/gtk-zoom-in.png
deleted file mode 100644
index 29e50e45d4a..00000000000
--- a/addons/base/static/src/img/icons/gtk-zoom-in.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/index1.jpeg b/addons/base/static/src/img/icons/index1.jpeg
deleted file mode 100644
index f43c68d79ec..00000000000
--- a/addons/base/static/src/img/icons/index1.jpeg
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/index2.jpeg b/addons/base/static/src/img/icons/index2.jpeg
deleted file mode 100644
index ec9d1eb6d3c..00000000000
--- a/addons/base/static/src/img/icons/index2.jpeg
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-accessories-archiver+.png b/addons/base/static/src/img/icons/terp-accessories-archiver+.png
deleted file mode 100644
index 14d6d02536e..00000000000
--- a/addons/base/static/src/img/icons/terp-accessories-archiver+.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-accessories-archiver-minus.png b/addons/base/static/src/img/icons/terp-accessories-archiver-minus.png
deleted file mode 100644
index 024c8f692d8..00000000000
--- a/addons/base/static/src/img/icons/terp-accessories-archiver-minus.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-accessories-archiver.png b/addons/base/static/src/img/icons/terp-accessories-archiver.png
deleted file mode 100644
index 8bcbe4566bc..00000000000
--- a/addons/base/static/src/img/icons/terp-accessories-archiver.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-account.png b/addons/base/static/src/img/icons/terp-account.png
deleted file mode 100644
index 30dea82a105..00000000000
--- a/addons/base/static/src/img/icons/terp-account.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-administration.png b/addons/base/static/src/img/icons/terp-administration.png
deleted file mode 100644
index ab129b2e4b3..00000000000
--- a/addons/base/static/src/img/icons/terp-administration.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-calendar.png b/addons/base/static/src/img/icons/terp-calendar.png
deleted file mode 100644
index 37206565792..00000000000
--- a/addons/base/static/src/img/icons/terp-calendar.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-call-start.png b/addons/base/static/src/img/icons/terp-call-start.png
deleted file mode 100644
index 602a1cdd4b8..00000000000
--- a/addons/base/static/src/img/icons/terp-call-start.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-camera_test.png b/addons/base/static/src/img/icons/terp-camera_test.png
deleted file mode 100644
index e97e0416de3..00000000000
--- a/addons/base/static/src/img/icons/terp-camera_test.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-check.png b/addons/base/static/src/img/icons/terp-check.png
deleted file mode 100644
index 003b09fdeb9..00000000000
--- a/addons/base/static/src/img/icons/terp-check.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-crm.png b/addons/base/static/src/img/icons/terp-crm.png
deleted file mode 100644
index fdac61ca92d..00000000000
--- a/addons/base/static/src/img/icons/terp-crm.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-dialog-close.png b/addons/base/static/src/img/icons/terp-dialog-close.png
deleted file mode 100644
index 8f51ec05fd6..00000000000
--- a/addons/base/static/src/img/icons/terp-dialog-close.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-document-new.png b/addons/base/static/src/img/icons/terp-document-new.png
deleted file mode 100644
index 2815cbb403f..00000000000
--- a/addons/base/static/src/img/icons/terp-document-new.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-dolar.png b/addons/base/static/src/img/icons/terp-dolar.png
deleted file mode 100644
index bca7021c82f..00000000000
--- a/addons/base/static/src/img/icons/terp-dolar.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-dolar_ok!.png b/addons/base/static/src/img/icons/terp-dolar_ok!.png
deleted file mode 100644
index b1005aae7b9..00000000000
--- a/addons/base/static/src/img/icons/terp-dolar_ok!.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-emblem-important.png b/addons/base/static/src/img/icons/terp-emblem-important.png
deleted file mode 100644
index a8321066abb..00000000000
--- a/addons/base/static/src/img/icons/terp-emblem-important.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-face-plain.png b/addons/base/static/src/img/icons/terp-face-plain.png
deleted file mode 100644
index ea90aaa7ef4..00000000000
--- a/addons/base/static/src/img/icons/terp-face-plain.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-folder-blue.png b/addons/base/static/src/img/icons/terp-folder-blue.png
deleted file mode 100644
index addc480d49a..00000000000
--- a/addons/base/static/src/img/icons/terp-folder-blue.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-folder-green.png b/addons/base/static/src/img/icons/terp-folder-green.png
deleted file mode 100644
index 206cd39603e..00000000000
--- a/addons/base/static/src/img/icons/terp-folder-green.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-folder-orange.png b/addons/base/static/src/img/icons/terp-folder-orange.png
deleted file mode 100644
index 726dbd7f00e..00000000000
--- a/addons/base/static/src/img/icons/terp-folder-orange.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-folder-violet.png b/addons/base/static/src/img/icons/terp-folder-violet.png
deleted file mode 100644
index c6f5cfb87ff..00000000000
--- a/addons/base/static/src/img/icons/terp-folder-violet.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-folder-yellow.png b/addons/base/static/src/img/icons/terp-folder-yellow.png
deleted file mode 100644
index cd7295dcdd7..00000000000
--- a/addons/base/static/src/img/icons/terp-folder-yellow.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-gdu-smart-failing.png b/addons/base/static/src/img/icons/terp-gdu-smart-failing.png
deleted file mode 100644
index a4448fd553e..00000000000
--- a/addons/base/static/src/img/icons/terp-gdu-smart-failing.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-gnome-cpu-frequency-applet+.png b/addons/base/static/src/img/icons/terp-gnome-cpu-frequency-applet+.png
deleted file mode 100644
index 23e246f3be9..00000000000
--- a/addons/base/static/src/img/icons/terp-gnome-cpu-frequency-applet+.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-go-home.png b/addons/base/static/src/img/icons/terp-go-home.png
deleted file mode 100644
index 912256bf7a7..00000000000
--- a/addons/base/static/src/img/icons/terp-go-home.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-go-month.png b/addons/base/static/src/img/icons/terp-go-month.png
deleted file mode 100644
index cf5e305053e..00000000000
--- a/addons/base/static/src/img/icons/terp-go-month.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-go-today.png b/addons/base/static/src/img/icons/terp-go-today.png
deleted file mode 100644
index 2a4dbeed49a..00000000000
--- a/addons/base/static/src/img/icons/terp-go-today.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-go-week.png b/addons/base/static/src/img/icons/terp-go-week.png
deleted file mode 100644
index b3ce6f562b2..00000000000
--- a/addons/base/static/src/img/icons/terp-go-week.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-go-year.png b/addons/base/static/src/img/icons/terp-go-year.png
deleted file mode 100644
index f45efc9dd0c..00000000000
--- a/addons/base/static/src/img/icons/terp-go-year.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-graph.png b/addons/base/static/src/img/icons/terp-graph.png
deleted file mode 100644
index 30dea82a105..00000000000
--- a/addons/base/static/src/img/icons/terp-graph.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-gtk-go-back-ltr.png b/addons/base/static/src/img/icons/terp-gtk-go-back-ltr.png
deleted file mode 100644
index a76138d2e0d..00000000000
--- a/addons/base/static/src/img/icons/terp-gtk-go-back-ltr.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-gtk-go-back-rtl.png b/addons/base/static/src/img/icons/terp-gtk-go-back-rtl.png
deleted file mode 100644
index 10d10b582fe..00000000000
--- a/addons/base/static/src/img/icons/terp-gtk-go-back-rtl.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-gtk-jump-to-ltr.png b/addons/base/static/src/img/icons/terp-gtk-jump-to-ltr.png
deleted file mode 100644
index fa517749d10..00000000000
--- a/addons/base/static/src/img/icons/terp-gtk-jump-to-ltr.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-gtk-jump-to-rtl.png b/addons/base/static/src/img/icons/terp-gtk-jump-to-rtl.png
deleted file mode 100644
index 7b5785c4963..00000000000
--- a/addons/base/static/src/img/icons/terp-gtk-jump-to-rtl.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-gtk-media-pause.png b/addons/base/static/src/img/icons/terp-gtk-media-pause.png
deleted file mode 100644
index 2896ad8e27f..00000000000
--- a/addons/base/static/src/img/icons/terp-gtk-media-pause.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-gtk-select-all.png b/addons/base/static/src/img/icons/terp-gtk-select-all.png
deleted file mode 100644
index b71a6493791..00000000000
--- a/addons/base/static/src/img/icons/terp-gtk-select-all.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-gtk-stop.png b/addons/base/static/src/img/icons/terp-gtk-stop.png
deleted file mode 100644
index 5fe021e19df..00000000000
--- a/addons/base/static/src/img/icons/terp-gtk-stop.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-hr.png b/addons/base/static/src/img/icons/terp-hr.png
deleted file mode 100644
index ba0241e6362..00000000000
--- a/addons/base/static/src/img/icons/terp-hr.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-idea.png b/addons/base/static/src/img/icons/terp-idea.png
deleted file mode 100644
index fd5e2a25f14..00000000000
--- a/addons/base/static/src/img/icons/terp-idea.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-locked.png b/addons/base/static/src/img/icons/terp-locked.png
deleted file mode 100644
index cd2b4c2c9c2..00000000000
--- a/addons/base/static/src/img/icons/terp-locked.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-mail-.png b/addons/base/static/src/img/icons/terp-mail-.png
deleted file mode 100644
index cbc85e4c000..00000000000
--- a/addons/base/static/src/img/icons/terp-mail-.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-mail-forward.png b/addons/base/static/src/img/icons/terp-mail-forward.png
deleted file mode 100644
index 3d4e694b6dc..00000000000
--- a/addons/base/static/src/img/icons/terp-mail-forward.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-mail-message-new.png b/addons/base/static/src/img/icons/terp-mail-message-new.png
deleted file mode 100644
index 25b4d5b5d50..00000000000
--- a/addons/base/static/src/img/icons/terp-mail-message-new.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-mail-replied.png b/addons/base/static/src/img/icons/terp-mail-replied.png
deleted file mode 100644
index 6615f4352cc..00000000000
--- a/addons/base/static/src/img/icons/terp-mail-replied.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-mail_delete.png b/addons/base/static/src/img/icons/terp-mail_delete.png
deleted file mode 100644
index 90fb5239f02..00000000000
--- a/addons/base/static/src/img/icons/terp-mail_delete.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-marketing.png b/addons/base/static/src/img/icons/terp-marketing.png
deleted file mode 100644
index 1b04b599734..00000000000
--- a/addons/base/static/src/img/icons/terp-marketing.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-mrp.png b/addons/base/static/src/img/icons/terp-mrp.png
deleted file mode 100644
index c2b4ea31ec3..00000000000
--- a/addons/base/static/src/img/icons/terp-mrp.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-partner.png b/addons/base/static/src/img/icons/terp-partner.png
deleted file mode 100644
index aab206a1d42..00000000000
--- a/addons/base/static/src/img/icons/terp-partner.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-personal+.png b/addons/base/static/src/img/icons/terp-personal+.png
deleted file mode 100644
index 8afa4d7041d..00000000000
--- a/addons/base/static/src/img/icons/terp-personal+.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-personal-.png b/addons/base/static/src/img/icons/terp-personal-.png
deleted file mode 100644
index a2554df3615..00000000000
--- a/addons/base/static/src/img/icons/terp-personal-.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-personal.png b/addons/base/static/src/img/icons/terp-personal.png
deleted file mode 100644
index 0890c4d0e51..00000000000
--- a/addons/base/static/src/img/icons/terp-personal.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-product.png b/addons/base/static/src/img/icons/terp-product.png
deleted file mode 100644
index 99f58d95a8b..00000000000
--- a/addons/base/static/src/img/icons/terp-product.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-project.png b/addons/base/static/src/img/icons/terp-project.png
deleted file mode 100644
index cd95ae84e43..00000000000
--- a/addons/base/static/src/img/icons/terp-project.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-purchase.png b/addons/base/static/src/img/icons/terp-purchase.png
deleted file mode 100644
index 1e801f57485..00000000000
--- a/addons/base/static/src/img/icons/terp-purchase.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-rating-rated.png b/addons/base/static/src/img/icons/terp-rating-rated.png
deleted file mode 100644
index 9bff03fe584..00000000000
--- a/addons/base/static/src/img/icons/terp-rating-rated.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-report.png b/addons/base/static/src/img/icons/terp-report.png
deleted file mode 100644
index ada36a2de24..00000000000
--- a/addons/base/static/src/img/icons/terp-report.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-sale.png b/addons/base/static/src/img/icons/terp-sale.png
deleted file mode 100644
index ba0241e6362..00000000000
--- a/addons/base/static/src/img/icons/terp-sale.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-stage.png b/addons/base/static/src/img/icons/terp-stage.png
deleted file mode 100644
index 591c1594f78..00000000000
--- a/addons/base/static/src/img/icons/terp-stage.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-stock.png b/addons/base/static/src/img/icons/terp-stock.png
deleted file mode 100644
index 0365dfdb8e1..00000000000
--- a/addons/base/static/src/img/icons/terp-stock.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-stock_align_left_24.png b/addons/base/static/src/img/icons/terp-stock_align_left_24.png
deleted file mode 100644
index 844367bb1a7..00000000000
--- a/addons/base/static/src/img/icons/terp-stock_align_left_24.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-stock_effects-object-colorize.png b/addons/base/static/src/img/icons/terp-stock_effects-object-colorize.png
deleted file mode 100644
index 0ffd95a740a..00000000000
--- a/addons/base/static/src/img/icons/terp-stock_effects-object-colorize.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-stock_format-default.png b/addons/base/static/src/img/icons/terp-stock_format-default.png
deleted file mode 100644
index e44b2b26be5..00000000000
--- a/addons/base/static/src/img/icons/terp-stock_format-default.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-stock_format-scientific.png b/addons/base/static/src/img/icons/terp-stock_format-scientific.png
deleted file mode 100644
index 01f83950804..00000000000
--- a/addons/base/static/src/img/icons/terp-stock_format-scientific.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-stock_symbol-selection.png b/addons/base/static/src/img/icons/terp-stock_symbol-selection.png
deleted file mode 100644
index 5773be57c9b..00000000000
--- a/addons/base/static/src/img/icons/terp-stock_symbol-selection.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-stock_zoom.png b/addons/base/static/src/img/icons/terp-stock_zoom.png
deleted file mode 100644
index e96f05e5905..00000000000
--- a/addons/base/static/src/img/icons/terp-stock_zoom.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-tools.png b/addons/base/static/src/img/icons/terp-tools.png
deleted file mode 100644
index 379f7617427..00000000000
--- a/addons/base/static/src/img/icons/terp-tools.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/icons/terp-translate.png b/addons/base/static/src/img/icons/terp-translate.png
deleted file mode 100644
index 5ab41d49343..00000000000
--- a/addons/base/static/src/img/icons/terp-translate.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/iconset-d-drop.gif b/addons/base/static/src/img/iconset-d-drop.gif
deleted file mode 100644
index 4907a927619..00000000000
--- a/addons/base/static/src/img/iconset-d-drop.gif
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/logo.png b/addons/base/static/src/img/logo.png
deleted file mode 100644
index 8f1c5c6085f..00000000000
--- a/addons/base/static/src/img/logo.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/partner.png b/addons/base/static/src/img/partner.png
deleted file mode 100644
index aab206a1d42..00000000000
--- a/addons/base/static/src/img/partner.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/placeholder.png b/addons/base/static/src/img/placeholder.png
deleted file mode 100644
index 25af75ee815..00000000000
--- a/addons/base/static/src/img/placeholder.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/product.png b/addons/base/static/src/img/product.png
deleted file mode 100644
index 99f58d95a8b..00000000000
--- a/addons/base/static/src/img/product.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/remove-shortcut.png b/addons/base/static/src/img/remove-shortcut.png
deleted file mode 100644
index 9bff03fe584..00000000000
--- a/addons/base/static/src/img/remove-shortcut.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/stock_person.png b/addons/base/static/src/img/stock_person.png
deleted file mode 100644
index 202cf0ee6c5..00000000000
--- a/addons/base/static/src/img/stock_person.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/throbber.gif b/addons/base/static/src/img/throbber.gif
deleted file mode 100644
index ded8d36d486..00000000000
--- a/addons/base/static/src/img/throbber.gif
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/throbber2.gif b/addons/base/static/src/img/throbber2.gif
deleted file mode 100644
index 5d2057ae0e7..00000000000
--- a/addons/base/static/src/img/throbber2.gif
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/toggle-a-bg.png b/addons/base/static/src/img/toggle-a-bg.png
deleted file mode 100644
index b9837ab233e..00000000000
--- a/addons/base/static/src/img/toggle-a-bg.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/ui/field_calendar.png b/addons/base/static/src/img/ui/field_calendar.png
deleted file mode 100644
index 99a1f3f9ef1..00000000000
--- a/addons/base/static/src/img/ui/field_calendar.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/ui/group-expanded.png b/addons/base/static/src/img/ui/group-expanded.png
deleted file mode 100644
index 3f16536e123..00000000000
--- a/addons/base/static/src/img/ui/group-expanded.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/ui/group-folded.png b/addons/base/static/src/img/ui/group-folded.png
deleted file mode 100644
index 2909b0c268f..00000000000
--- a/addons/base/static/src/img/ui/group-folded.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/img/warning.png b/addons/base/static/src/img/warning.png
deleted file mode 100644
index cbfb25a89cd..00000000000
--- a/addons/base/static/src/img/warning.png
+++ /dev/null
Binary files differ
diff --git a/addons/base/static/src/js/boot.js b/addons/base/static/src/js/boot.js
deleted file mode 100644
index 8fe62d2e5a4..00000000000
--- a/addons/base/static/src/js/boot.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/*---------------------------------------------------------
- * OpenERP Web Boostrap Code
- *---------------------------------------------------------*/
-
-/**
- * @name openerp
- * @namespace openerp
- * @namespace window.openerp
- */
-(function() {
- if (this.openerp)
- return;
- var session_counter = 0;
-
- var openerp = this.openerp = {
- // Per session namespace
- // openerp.<module> will map to
- // openerp.sessions.sessionname.<module> using a closure
- sessions: {},
- /**
- * OpenERP instance constructor
- *
- * @param {Boolean} skip_init if true, skips the built-in initialization
- */
- init: function(skip_init) {
- var new_instance = {
- // links to the global openerp
- _openerp: openerp,
- // Only base will be loaded, the rest will be by loaded by
- // openerp.base.Connection on the first connection
- _modules_loaded: false,
- // this unique id will be replaced by hostname_databasename by
- // openerp.base.Connection on the first connection
- _session_id: "session" + session_counter++,
- base: {},
- web_mobile: {}
- };
- openerp.sessions[new_instance._session_id] = new_instance;
- if (!skip_init){
- openerp.base(new_instance);
- }
- return new_instance;
- }
- };
-})();
-
-/*---------------------------------------------------------
- * OpenERP Web base module split
- *---------------------------------------------------------*/
-
-openerp.base = function(instance) {
- openerp.base.core(instance);
- if (openerp.base.dates) {
- openerp.base.dates(instance);
- }
- openerp.base.formats(instance);
- openerp.base.chrome(instance);
- openerp.base.data(instance);
- files = ["views","search","list","form","list_editable","web_mobile","view_tree","data_export","view_editor"];
- for(i=0; i<files.length; i++) {
- if(openerp.base[files[i]]) {
- openerp.base[files[i]](instance);
- }
- }
-};
-
-// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js
deleted file mode 100644
index ee20e393d67..00000000000
--- a/addons/base/static/src/js/chrome.js
+++ /dev/null
@@ -1,940 +0,0 @@
-/*---------------------------------------------------------
- * OpenERP Web chrome
- *---------------------------------------------------------*/
-
-openerp.base.chrome = function(openerp) {
-
-openerp.base.Notification = openerp.base.Widget.extend({
- init: function(parent, element_id) {
- this._super(parent, element_id);
- this.$element.notify({
- speed: 500,
- expires: 1500
- });
- },
- notify: function(title, text) {
- this.$element.notify('create', {
- title: title,
- text: text
- });
- },
- warn: function(title, text) {
- this.$element.notify('create', 'oe_notification_alert', {
- title: title,
- text: text
- });
- }
-});
-
-openerp.base.Dialog = openerp.base.OldWidget.extend({
- dialog_title: "",
- identifier_prefix: 'dialog',
- init: function (parent, dialog_options) {
- var self = this;
- this._super(parent);
- this.dialog_options = {
- modal: true,
- width: 'auto',
- min_width: 0,
- max_width: '100%',
- height: 'auto',
- min_height: 0,
- max_height: '100%',
- autoOpen: false,
- buttons: {},
- beforeClose: function () { self.on_close(); }
- };
- for (var f in this) {
- if (f.substr(0, 10) == 'on_button_') {
- this.dialog_options.buttons[f.substr(10)] = this[f];
- }
- }
- if (dialog_options) {
- this.set_options(dialog_options);
- }
- },
- set_options: function(options) {
- options = options || {};
- options.width = this.get_width(options.width || this.dialog_options.width);
- options.min_width = this.get_width(options.min_width || this.dialog_options.min_width);
- options.max_width = this.get_width(options.max_width || this.dialog_options.max_width);
- options.height = this.get_height(options.height || this.dialog_options.height);
- options.min_height = this.get_height(options.min_height || this.dialog_options.min_height);
- options.max_height = this.get_height(options.max_height || this.dialog_options.max_width);
-
- if (options.width !== 'auto') {
- if (options.width > options.max_width) options.width = options.max_width;
- if (options.width < options.min_width) options.width = options.min_width;
- }
- if (options.height !== 'auto') {
- if (options.height > options.max_height) options.height = options.max_height;
- if (options.height < options.min_height) options.height = options.min_height;
- }
- if (!options.title && this.dialog_title) {
- options.title = this.dialog_title;
- }
- _.extend(this.dialog_options, options);
- },
- get_width: function(val) {
- return this.get_size(val.toString(), $(window.top).width());
- },
- get_height: function(val) {
- return this.get_size(val.toString(), $(window.top).height());
- },
- get_size: function(val, available_size) {
- if (val === 'auto') {
- return val;
- } else if (val.slice(-1) == "%") {
- return Math.round(available_size / 100 * parseInt(val.slice(0, -1), 10));
- } else {
- return parseInt(val, 10);
- }
- },
- start: function () {
- this.$dialog = $('<div id="' + this.element_id + '"></div>').dialog(this.dialog_options);
- this._super();
- return this;
- },
- open: function(dialog_options) {
- // TODO fme: bind window on resize
- if (this.template) {
- this.$element.html(this.render());
- }
- this.set_options(dialog_options);
- this.$dialog.dialog(this.dialog_options).dialog('open');
- return this;
- },
- close: function() {
- // Closes the dialog but leave it in a state where it could be opened again.
- this.$dialog.dialog('close');
- },
- on_close: function() {
- },
- stop: function () {
- // Destroy widget
- this.close();
- this.$dialog.dialog('destroy');
- }
-});
-
-openerp.base.CrashManager = openerp.base.Dialog.extend({
- identifier_prefix: 'dialog_crash',
- init: function(parent) {
- this._super(parent);
- this.session.on_rpc_error.add(this.on_rpc_error);
- },
- on_button_Ok: function() {
- this.close();
- },
- on_rpc_error: function(error) {
- this.error = error;
- if (error.data.fault_code) {
- var split = error.data.fault_code.split('\n')[0].split(' -- ');
- if (split.length > 1) {
- error.type = split.shift();
- error.data.fault_code = error.data.fault_code.substr(error.type.length + 4);
- }
- }
- if (error.code === 200 && error.type) {
- this.dialog_title = "OpenERP " + _.capitalize(error.type);
- this.template = 'DialogWarning';
- this.open({
- width: 'auto',
- height: 'auto'
- });
- } else {
- this.dialog_title = "OpenERP Error";
- this.template = 'DialogTraceback';
- this.open({
- width: 'auto',
- height: 'auto'
- });
- }
- }
-});
-
-openerp.base.Loading = openerp.base.Widget.extend({
- init: function(parent, element_id) {
- this._super(parent, element_id);
- this.count = 0;
- this.session.on_rpc_request.add_first(this.on_rpc_event, 1);
- this.session.on_rpc_response.add_last(this.on_rpc_event, -1);
- },
- on_rpc_event : function(increment) {
- this.count += increment;
- if (this.count) {
- //this.$element.html(QWeb.render("Loading", {}));
- this.$element.html("Loading ("+this.count+")");
- this.$element.show();
- } else {
- this.$element.fadeOut();
- }
- }
-});
-
-openerp.base.Database = openerp.base.Widget.extend({
- init: function(parent, element_id, option_id) {
- this._super(parent, element_id);
- this.$option_id = $('#' + option_id);
- },
- start: function() {
- this.$element.html(QWeb.render("Database", this));
- this.$element.closest(".openerp")
- .removeClass("login-mode")
- .addClass("database_block");
-
- var self = this;
-
- var fetch_db = this.rpc("/base/database/get_list", {}, function(result) {
- self.db_list = result.db_list;
- });
- var fetch_langs = this.rpc("/base/session/get_lang_list", {}, function(result) {
- if (result.error) {
- self.display_error(result);
- return;
- }
- self.lang_list = result.lang_list;
- });
- $.when(fetch_db, fetch_langs).then(function () {self.do_create();});
-
- this.$element.find('#db-create').click(this.do_create);
- this.$element.find('#db-drop').click(this.do_drop);
- this.$element.find('#db-backup').click(this.do_backup);
- this.$element.find('#db-restore').click(this.do_restore);
- this.$element.find('#db-change-password').click(this.do_change_password);
- this.$element.find('#back-to-login').click(function() {
- self.stop();
- });
- },
- stop: function () {
- this.$option_id.empty();
-
- this.$element
- .find('#db-create, #db-drop, #db-backup, #db-restore, #db-change-password, #back-to-login')
- .unbind('click')
- .end()
- .closest(".openerp")
- .addClass("login-mode")
- .removeClass("database_block")
- .end()
- .empty();
-
- },
- /**
- * Converts a .serializeArray() result into a dict. Does not bother folding
- * multiple identical keys into an array, last key wins.
- *
- * @param {Array} array
- */
- to_object: function (array) {
- var result = {};
- _(array).each(function (record) {
- result[record.name] = record.value;
- });
- return result;
- },
- /**
- * Waits until the new database is done creating, then unblocks the UI and
- * logs the user in as admin
- *
- * @param {Number} db_creation_id identifier for the db-creation operation, used to fetch the current installation progress
- * @param {Object} info info fields for this database creation
- * @param {String} info.db name of the database being created
- * @param {String} info.password super-admin password for the database
- */
- wait_for_newdb: function (db_creation_id, info) {
- var self = this;
- self.rpc('/base/database/progress', {
- id: db_creation_id,
- password: info.password
- }, function (result) {
- var progress = result[0];
- // I'd display a progress bar, but turns out the progress status
- // the server report kind-of blows goats: it's at 0 for ~75% of
- // the installation, then jumps to 75%, then jumps down to either
- // 0 or ~40%, then back up to 75%, then terminates. Let's keep that
- // mess hidden behind a not-very-useful but not overly weird
- // message instead.
- if (progress < 1) {
- setTimeout(function () {
- self.wait_for_newdb(db_creation_id, info);
- }, 500);
- return;
- }
-
- var admin = result[1][0];
- setTimeout(function () {
- self.stop();
- self.widget_parent.do_login(
- info.db, admin.login, admin.password);
- $.unblockUI();
- });
- });
- },
- /**
- * Displays an error dialog resulting from the various RPC communications
- * failing over themselves
- *
- * @param {Object} error error description
- * @param {String} error.title title of the error dialog
- * @param {String} error.error message of the error dialog
- */
- display_error: function (error) {
- return $('<div>').dialog({
- modal: true,
- title: error.title,
- buttons: {
- Ok: function() {
- $(this).dialog("close");
- }
- }
- }).html(error.error);
- },
- do_create: function() {
- var self = this;
- self.$option_id.html(QWeb.render("Database.CreateDB", self));
- self.$option_id.find("form[name=create_db_form]").validate({
- submitHandler: function (form) {
- var fields = $(form).serializeArray();
- $.blockUI({message:'<img src="/base/static/src/img/throbber2.gif">'});
- self.rpc("/base/database/create", {'fields': fields}, function(result) {
- if (result.error) {
- $.unblockUI();
- self.display_error(result);
- return;
- }
- self.db_list.push(self.to_object(fields)['db_name']);
- self.db_list.sort();
- var form_obj = self.to_object(fields);
- self.wait_for_newdb(result, {
- password: form_obj['super_admin_pwd'],
- db: form_obj['db_name']
- });
- });
- }
- });
- },
- do_drop: function() {
- var self = this;
- self.$option_id.html(QWeb.render("DropDB", self));
- self.$option_id.find("form[name=drop_db_form]").validate({
- submitHandler: function (form) {
- var $form = $(form),
- fields = $form.serializeArray(),
- $db_list = $form.find('select[name=drop_db]'),
- db = $db_list.val();
-
- if (!confirm("Do you really want to delete the database: " + db + " ?")) {
- return;
- }
- self.rpc("/base/database/drop", {'fields': fields}, function(result) {
- if (result.error) {
- self.display_error(result);
- return;
- }
- $db_list.find(':selected').remove();
- self.db_list.splice(_.indexOf(self.db_list, db, true), 1);
- self.notification.notify("Dropping database", "The database '" + db + "' has been dropped");
- });
- }
- });
- },
- wait_for_file: function (token, cleanup) {
- var self = this,
- cookie_name = 'fileToken',
- cookie_length = cookie_name.length;
- this.backup_timer = setInterval(function () {
- var cookies = document.cookie.split(';');
- for(var i=0; i<cookies.length; ++i) {
- var cookie = cookies[i].replace(/^\s*/, '');
- if(!cookie.indexOf(cookie_name) === 0) { continue; }
- var cookie_val = cookie.substring(cookie_length + 1);
- if(parseInt(cookie_val, 10) !== token) { continue; }
-
- // clear waiter
- clearInterval(self.backup_timer);
- // clear cookie
- document.cookie = _.sprintf("%s=;expires=%s;path=/",
- cookie_name, new Date().toGMTString());
-
- if (cleanup) { cleanup(); }
- }
- }, 200);
- },
- do_backup: function() {
- var self = this;
- self.$option_id.html(QWeb.render("BackupDB", self));
-
- self.$option_id.find("form[name=backup_db_form]").validate({
- submitHandler: function (form) {
- $.blockUI({message:'<img src="/base/static/src/img/throbber2.gif">'});
- // need to detect when the file is done downloading (not used
- // yet, but we'll need it to fix the UI e.g. with a throbber
- // while dump is being generated), iframe load event only fires
- // when the iframe content loads, so we need to go smarter:
- // http://geekswithblogs.net/GruffCode/archive/2010/10/28/detecting-the-file-download-dialog-in-the-browser.aspx
- var $target = $('#backup-target'),
- token = new Date().getTime();
- if (!$target.length) {
- $target = $('<iframe id="backup-target" style="display: none;">')
- .appendTo(document.body)
- .load(function () {
- $.unblockUI();
- clearInterval(self.backup_timer);
- var error = this.contentDocument.body
- .firstChild.data
- .split('|');
- self.display_error({
- title: error[0],
- error: error[1]
- });
- });
- }
- $(form).find('input[name=token]').val(token);
- form.submit();
-
- self.wait_for_file(token, function () {
- $.unblockUI();
- });
- }
- });
- },
- do_restore: function() {
- var self = this;
- self.$option_id.html(QWeb.render("RestoreDB", self));
-
- self.$option_id.find("form[name=restore_db_form]").validate({
- submitHandler: function (form) {
- $.blockUI({message:'<img src="/base/static/src/img/throbber2.gif">'});
- $(form).ajaxSubmit({
- url: '/base/database/restore',
- type: 'POST',
- resetForm: true,
- success: function (body) {
- // TODO: ui manipulations
- // note: response objects don't work, but we have the
- // HTTP body of the response~~
-
- // If empty body, everything went fine
- if (!body) { return; }
-
- if (body.indexOf('403 Forbidden') !== -1) {
- self.display_error({
- title: 'Access Denied',
- error: 'Incorrect super-administrator password'
- })
- } else {
- self.display_error({
- title: 'Restore Database',
- error: 'Could not restore the database'
- })
- }
- },
- complete: function () {
- $.unblockUI();
- }
- });
- }
- });
- },
- do_change_password: function() {
- var self = this;
- self.$option_id.html(QWeb.render("Change_DB_Pwd", self));
-
- self.$option_id.find("form[name=change_pwd_form]").validate({
- messages: {
- old_pwd: "Please enter your previous password",
- new_pwd: "Please enter your new password",
- confirm_pwd: {
- required: "Please confirm your new password",
- equalTo: "The confirmation does not match the password"
- }
- },
- submitHandler: function (form) {
- self.rpc("/base/database/change_password", {
- 'fields': $(form).serializeArray()
- }, function(result) {
- if (result.error) {
- self.display_error(result);
- return;
- }
- self.notification.notify("Changed Password", "Password has been changed successfully");
- });
- }
- });
- }
-});
-
-openerp.base.Login = openerp.base.Widget.extend({
- remember_creditentials: true,
-
- init: function(parent, element_id) {
- this._super(parent, element_id);
- this.has_local_storage = typeof(localStorage) != 'undefined';
- this.selected_db = null;
- this.selected_login = null;
-
- if (this.has_local_storage && this.remember_creditentials) {
- this.selected_db = localStorage.getItem('last_db_login_success');
- this.selected_login = localStorage.getItem('last_login_login_success');
- }
- if (jQuery.deparam(jQuery.param.querystring()).debug != undefined) {
- this.selected_password = this.selected_password || "a";
- }
- },
- start: function() {
- var self = this;
- this.rpc("/base/database/get_list", {}, function(result) {
- self.db_list = result.db_list;
- self.display();
- }, function() {
- self.display();
- });
- },
- display: function() {
- var self = this;
-
- this.$element.html(QWeb.render("Login", this));
- this.database = new openerp.base.Database(
- this, "oe_database", "oe_db_options");
-
- this.$element.find('#oe-db-config').click(function() {
- self.database.start();
- });
-
- this.$element.find("form").submit(this.on_submit);
- },
- on_login_invalid: function() {
- this.$element.closest(".openerp").addClass("login-mode");
- },
- on_login_valid: function() {
- this.$element.closest(".openerp").removeClass("login-mode");
- },
- on_submit: function(ev) {
- ev.preventDefault();
- var $e = this.$element;
- var db = $e.find("form [name=db]").val();
- var login = $e.find("form input[name=login]").val();
- var password = $e.find("form input[name=password]").val();
-
- this.do_login(db, login, password);
- },
- /**
- * Performs actual login operation, and UI-related stuff
- *
- * @param {String} db database to log in
- * @param {String} login user login
- * @param {String} password user password
- */
- do_login: function (db, login, password) {
- var self = this;
- this.session.session_login(db, login, password, function() {
- if(self.session.session_is_valid()) {
- if (self.has_local_storage) {
- if(self.remember_creditentials) {
- localStorage.setItem('last_db_login_success', db);
- localStorage.setItem('last_login_login_success', login);
- } else {
- localStorage.setItem('last_db_login_success', '');
- localStorage.setItem('last_login_login_success', '');
- }
- }
- self.on_login_valid();
- } else {
- self.$element.addClass("login_invalid");
- self.on_login_invalid();
- }
- });
- },
- do_ask_login: function(continuation) {
- this.on_login_invalid();
- this.$element
- .removeClass("login_invalid");
- this.on_login_valid.add({
- position: "last",
- unique: true,
- callback: continuation
- });
- },
- on_logout: function() {
- this.session.logout();
- }
-});
-
-openerp.base.Header = openerp.base.Widget.extend({
- template: "Header",
- identifier_prefix: 'oe-app-header-',
- init: function(parent) {
- this._super(parent);
- this.qs = "?" + jQuery.param.querystring();
- this.$content = $();
- },
- start: function() {
- this._super();
- },
- do_update: function () {
- this.$content = $(QWeb.render("Header-content", {widget: this}));
- this.$content.appendTo(this.$element);
- this.$element.find(".logout").click(this.on_logout);
- this.$element.find("a.preferences").click(this.on_preferences);
- return this.shortcut_load();
- },
- do_reset: function() {
- this.$content.remove();
- },
- shortcut_load :function(){
- var self = this,
- sc = self.session.shortcuts,
- shortcuts_ds = new openerp.base.DataSet(this, 'ir.ui.view_sc');
- // TODO: better way to communicate between sections.
- // sc.bindings, because jquery does not bind/trigger on arrays...
- if (!sc.binding) {
- sc.binding = {};
- $(sc.binding).bind({
- 'add': function (e, attrs) {
- shortcuts_ds.create(attrs, function (out) {
- $('<li>', {
- 'data-shortcut-id':out.result,
- 'data-id': attrs.res_id
- }).text(attrs.name)
- .appendTo(self.$element.find('.oe-shortcuts ul'));
- attrs.id = out.result;
- sc.push(attrs);
- });
- },
- 'remove-current': function () {
- var menu_id = self.session.active_id;
- var $shortcut = self.$element
- .find('.oe-shortcuts li[data-id=' + menu_id + ']');
- var shortcut_id = $shortcut.data('shortcut-id');
- $shortcut.remove();
- shortcuts_ds.unlink([shortcut_id]);
- var sc_new = _.reject(sc, function(shortcut){ return shortcut_id === shortcut.id});
- sc.splice(0, sc.length);
- sc.push.apply(sc, sc_new);
- }
- });
- }
- return this.rpc('/base/session/sc_list', {}, function(shortcuts) {
- sc.splice(0, sc.length);
- sc.push.apply(sc, shortcuts);
-
- self.$element.find('.oe-shortcuts')
- .html(QWeb.render('Shortcuts', {'shortcuts': shortcuts}))
- .undelegate('li', 'click')
-
- .delegate('li', 'click', function(e) {
- e.stopPropagation();
- var id = $(this).data('id');
- self.session.active_id = id;
- self.rpc('/base/menu/action', {'menu_id':id}, function(ir_menu_data) {
- if (ir_menu_data.action.length){
- self.on_action(ir_menu_data.action[0][2]);
- }
- });
- });
- });
- },
-
- on_action: function(action) {
- },
- on_preferences: function(){
- var self = this;
- var action_manager = new openerp.base.ActionManager(this);
- var dataset = new openerp.base.DataSet (this,'res.users',this.context);
- dataset.call ('action_get','',function (result){
- self.rpc('/base/action/load', {action_id:result}, function(result){
- action_manager.do_action(_.extend(result['result'], {
- res_id: self.session.uid,
- res_model: 'res.users',
- flags: {
- action_buttons: false,
- search_view: false,
- sidebar: false,
- views_switcher: false,
- pager: false
- }
- }));
- });
- });
- this.dialog = new openerp.base.Dialog(this,{
- modal: true,
- title: 'Preferences',
- width: 600,
- height: 500,
- buttons: {
- "Change password": function(){
- self.change_password();
- },
- Cancel: function(){
- $(this).dialog('destroy');
- },
- Save: function(){
- var inner_viewmanager = action_manager.inner_viewmanager;
- inner_viewmanager.views[inner_viewmanager.active_view].controller.do_save(function(){
- inner_viewmanager.start();
- });
- $(this).dialog('destroy')
- }
- }
- });
- this.dialog.start().open();
- action_manager.appendTo(this.dialog);
- action_manager.render(this.dialog);
- },
-
- change_password :function() {
- var self = this;
- this.dialog = new openerp.base.Dialog(this,{
- modal : true,
- title : 'Change Password',
- width : 'auto',
- height : 'auto'
- });
- this.dialog.start().open();
- this.dialog.$element.html(QWeb.render("Change_Pwd", self));
- this.dialog.$element.find("form[name=change_password_form]").validate({
- submitHandler: function (form) {
- self.rpc("/base/session/change_password",{
- 'fields': $(form).serializeArray()
- }, function(result) {
- if (result.error) {
- self.display_error(result);
- return;
- }
- else {
- if (result.new_password) {
- self.session.password = result.new_password;
- var session = new openerp.base.Session(self.session.server, self.session.port);
- session.start();
- session.session_login(self.session.db, self.session.login, self.session.password)
- }
- }
- self.notification.notify("Changed Password", "Password has been changed successfully");
- self.dialog.close();
- });
- }
- });
-},
- display_error: function (error) {
- return $('<div>').dialog({
- modal: true,
- title: error.title,
- buttons: {
- Ok: function() {
- $(this).dialog("close");
- }
- }
- }).html(error.error);
- },
- on_logout: function() {
- this.$element.find('.oe-shortcuts ul').empty();
- }
-});
-
-openerp.base.Menu = openerp.base.Widget.extend({
- init: function(parent, element_id, secondary_menu_id) {
- this._super(parent, element_id);
- this.secondary_menu_id = secondary_menu_id;
- this.$secondary_menu = $("#" + secondary_menu_id).hide();
- this.menu = false;
- },
- start: function() {
- this.rpc("/base/menu/load", {}, this.on_loaded);
- },
- on_loaded: function(data) {
- this.data = data;
- this.$element.html(QWeb.render("Menu", this.data));
- for (var i = 0; i < this.data.data.children.length; i++) {
- var v = { menu : this.data.data.children[i] };
- this.$secondary_menu.append(QWeb.render("Menu.secondary", v));
- }
- this.$secondary_menu.find("div.menu_accordion").accordion({
- animated : false,
- autoHeight : false,
- icons : false
- });
- this.$secondary_menu.find("div.submenu_accordion").accordion({
- animated : false,
- autoHeight : false,
- active: false,
- collapsible: true,
- header: 'h4'
- });
-
- this.$element.add(this.$secondary_menu).find("a").click(this.on_menu_click);
- },
- on_menu_click: function(ev, id) {
- id = id || 0;
- var $menu, $parent, $secondary;
-
- if (id) {
- // We can manually activate a menu with it's id (for hash url mapping)
- $menu = this.$element.find('a[data-menu=' + id + ']');
- if (!$menu.length) {
- $menu = this.$secondary_menu.find('a[data-menu=' + id + ']');
- }
- } else {
- $menu = $(ev.currentTarget);
- id = $menu.data('menu');
- }
- if (this.$secondary_menu.has($menu).length) {
- $secondary = $menu.parents('.menu_accordion');
- $parent = this.$element.find('a[data-menu=' + $secondary.data('menu-parent') + ']');
- } else {
- $parent = $menu;
- $secondary = this.$secondary_menu.find('.menu_accordion[data-menu-parent=' + $menu.attr('data-menu') + ']');
- }
-
- this.$secondary_menu.find('.menu_accordion').hide();
- // TODO: ui-accordion : collapse submenus and expand the good one
- $secondary.show();
-
- if (id) {
- this.session.active_id = id;
- this.rpc('/base/menu/action', {'menu_id': id},
- this.on_menu_action_loaded);
- }
-
- $('.active', this.$element.add(this.$secondary_menu.show())).removeClass('active');
- $parent.addClass('active');
- $menu.addClass('active');
- $menu.parent('h4').addClass('active');
-
- return !$menu.is(".leaf");
- },
- on_menu_action_loaded: function(data) {
- var self = this;
- if (data.action.length) {
- var action = data.action[0][2];
- self.on_action(action);
- }
- },
- on_action: function(action) {
- }
-});
-
-openerp.base.Homepage = openerp.base.Widget.extend({
-});
-
-openerp.base.Preferences = openerp.base.Widget.extend({
-});
-
-openerp.base.WebClient = openerp.base.Widget.extend({
- init: function(element_id) {
- this._super(null, element_id);
- openerp.webclient = this;
-
- QWeb.add_template("/base/static/src/xml/base.xml");
- var params = {};
- if(jQuery.param != undefined && jQuery.deparam(jQuery.param.querystring()).kitten != undefined) {
- this.$element.addClass("kitten-mode-activated");
- }
- this.$element.html(QWeb.render("Interface", params));
-
- this.session = new openerp.base.Session();
- this.loading = new openerp.base.Loading(this,"oe_loading");
- this.crashmanager = new openerp.base.CrashManager(this);
- this.crashmanager.start();
-
- // Do you autorize this ? will be replaced by notify() in controller
- openerp.base.Widget.prototype.notification = new openerp.base.Notification(this, "oe_notification");
-
-
- this.header = new openerp.base.Header(this);
- this.login = new openerp.base.Login(this, "oe_login");
- this.header.on_logout.add(this.login.on_logout);
- this.header.on_action.add(this.on_menu_action);
-
- this.session.on_session_invalid.add(this.login.do_ask_login);
- this.session.on_session_valid.add_last(this.header.do_update);
- this.session.on_session_invalid.add_last(this.header.do_reset);
- this.session.on_session_valid.add_last(this.on_logged);
-
- this.menu = new openerp.base.Menu(this, "oe_menu", "oe_secondary_menu");
- this.menu.on_action.add(this.on_menu_action);
- },
- start: function() {
- this.header.appendTo($("#oe_header"));
- this.session.start();
- this.login.start();
- this.menu.start();
- this.notification.notify("OpenERP Client", "The openerp client has been initialized.");
- },
- on_logged: function() {
- if(this.action_manager)
- this.action_manager.stop();
- this.action_manager = new openerp.base.ActionManager(this);
- this.action_manager.appendTo($("#oe_app"));
-
- // if using saved actions, load the action and give it to action manager
- var parameters = jQuery.deparam(jQuery.param.querystring());
- if (parameters["s_action"] != undefined) {
- var key = parseInt(parameters["s_action"], 10);
- var self = this;
- this.rpc("/base/session/get_session_action", {key:key}, function(action) {
- self.action_manager.do_action(action);
- });
- } else if (openerp._modules_loaded) { // TODO: find better option than this
- this.load_url_state()
- } else {
- this.session.on_modules_loaded.add({
- callback: $.proxy(this, 'load_url_state'),
- unique: true,
- position: 'last'
- })
- }
- },
- /**
- * Loads state from URL if any, or checks if there is a home action and
- * loads that, assuming we're at the index
- */
- load_url_state: function () {
- var self = this;
- // TODO: add actual loading if there is url state to unpack, test on window.location.hash
-
- // not logged in
- if (!this.session.uid) { return; }
- var ds = new openerp.base.DataSetSearch(this, 'res.users');
- ds.read_ids([this.session.uid], ['action_id'], function (users) {
- var home_action = users[0].action_id;
- if (!home_action) {
- self.default_home();
- return;
- }
- self.execute_home_action(home_action[0], ds);
- })
- },
- default_home: function () {
- },
- /**
- * Bundles the execution of the home action
- *
- * @param {Number} action action id
- * @param {openerp.base.DataSet} dataset action executor
- */
- execute_home_action: function (action, dataset) {
- var self = this;
- this.rpc('/base/action/load', {
- action_id: action,
- context: dataset.get_context()
- }, function (meh) {
- var action = meh.result;
- action.context = _.extend(action.context || {}, {
- active_id: false,
- active_ids: [false],
- active_model: dataset.model
- });
- self.action_manager.do_action(action);
- });
- },
- on_menu_action: function(action) {
- this.action_manager.do_action(action);
- },
- do_about: function() {
- }
-});
-
-};
-
-// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
diff --git a/addons/base/static/src/js/core.js b/addons/base/static/src/js/core.js
deleted file mode 100644
index 4cd46504a69..00000000000
--- a/addons/base/static/src/js/core.js
+++ /dev/null
@@ -1,915 +0,0 @@
-/*---------------------------------------------------------
- * OpenERP Web core
- *--------------------------------------------------------*/
-
-openerp.base.core = function(openerp) {
-/**
- * John Resig Class with factory improvement
- */
-(function() {
- var initializing = false,
- fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
- // The base Class implementation (does nothing)
- /**
- * @class
- */
- openerp.base.Class = function(){};
-
- // Create a new Class that inherits from this class
- openerp.base.Class.extend = function(prop) {
- var _super = this.prototype;
-
- // Instantiate a base class (but only create the instance,
- // don't run the init constructor)
- initializing = true;
- var prototype = new this();
- initializing = false;
-
- // Copy the properties over onto the new prototype
- for (var name in prop) {
- // Check if we're overwriting an existing function
- prototype[name] = typeof prop[name] == "function" &&
- typeof _super[name] == "function" &&
- fnTest.test(prop[name]) ?
- (function(name, fn) {
- return function() {
- var tmp = this._super;
-
- // Add a new ._super() method that is the same
- // method but on the super-class
- this._super = _super[name];
-
- // The method only need to be bound temporarily, so
- // we remove it when we're done executing
- var ret = fn.apply(this, arguments);
- this._super = tmp;
-
- return ret;
- };
- })(name, prop[name]) :
- prop[name];
- }
-
- // The dummy class constructor
- function Class() {
- // All construction is actually done in the init method
- if (!initializing && this.init) {
- var ret = this.init.apply(this, arguments);
- if (ret) { return ret; }
- }
- return this;
- }
- Class.include = function (properties) {
- for (var name in properties) {
- if (typeof properties[name] !== 'function'
- || !fnTest.test(properties[name])) {
- prototype[name] = properties[name];
- } else if (typeof prototype[name] === 'function'
- && prototype.hasOwnProperty(name)) {
- prototype[name] = (function (name, fn, previous) {
- return function () {
- var tmp = this._super;
- this._super = previous;
- var ret = fn.apply(this, arguments);
- this._super = tmp;
- return ret;
- }
- })(name, properties[name], prototype[name]);
- } else if (typeof _super[name] === 'function') {
- prototype[name] = (function (name, fn) {
- return function () {
- var tmp = this._super;
- this._super = _super[name];
- var ret = fn.apply(this, arguments);
- this._super = tmp;
- return ret;
- }
- })(name, properties[name]);
- }
- }
- };
-
- // Populate our constructed prototype object
- Class.prototype = prototype;
-
- // Enforce the constructor to be what we expect
- Class.constructor = Class;
-
- // And make this class extendable
- Class.extend = arguments.callee;
-
- return Class;
- };
-})();
-
-openerp.base.callback = function(obj, method) {
- var callback = function() {
- var args = Array.prototype.slice.call(arguments);
- var r;
- for(var i = 0; i < callback.callback_chain.length; i++) {
- var c = callback.callback_chain[i];
- if(c.unique) {
- callback.callback_chain.splice(i, 1);
- i -= 1;
- }
- r = c.callback.apply(c.self, c.args.concat(args));
- // TODO special value to stop the chain
- // openerp.base.callback_stop
- }
- return r;
- };
- callback.callback_chain = [];
- callback.add = function(f) {
- if(typeof(f) == 'function') {
- f = { callback: f, args: Array.prototype.slice.call(arguments, 1) };
- }
- f.self = f.self || null;
- f.args = f.args || [];
- f.unique = !!f.unique;
- if(f.position == 'last') {
- callback.callback_chain.push(f);
- } else {
- callback.callback_chain.unshift(f);
- }
- return callback;
- };
- callback.add_first = function(f) {
- return callback.add.apply(null,arguments);
- };
- callback.add_last = function(f) {
- return callback.add({
- callback: f,
- args: Array.prototype.slice.call(arguments, 1),
- position: "last"
- });
- };
-
- return callback.add({
- callback: method,
- self:obj,
- args:Array.prototype.slice.call(arguments, 2)
- });
-};
-
-/**
- * Generates an inherited class that replaces all the methods by null methods (methods
- * that does nothing and always return undefined).
- *
- * @param {Class} claz
- * @param {dict} add Additional functions to override.
- * @return {Class}
- */
-openerp.base.generate_null_object_class = function(claz, add) {
- var newer = {};
- var copy_proto = function(prototype) {
- for (var name in prototype) {
- if(typeof prototype[name] == "function") {
- newer[name] = function() {};
- }
- }
- if (prototype.prototype)
- copy_proto(prototype.prototype);
- };
- copy_proto(claz.prototype);
- newer.init = openerp.base.Widget.prototype.init;
- var tmpclass = claz.extend(newer);
- return tmpclass.extend(add || {});
-};
-
-/**
- * Base error for lookup failure
- *
- * @class
- */
-openerp.base.NotFound = openerp.base.Class.extend( /** @lends openerp.base.NotFound# */ {
-});
-openerp.base.KeyNotFound = openerp.base.NotFound.extend( /** @lends openerp.base.KeyNotFound# */ {
- /**
- * Thrown when a key could not be found in a mapping
- *
- * @constructs
- * @extends openerp.base.NotFound
- * @param {String} key the key which could not be found
- */
- init: function (key) {
- this.key = key;
- },
- toString: function () {
- return "The key " + this.key + " was not found";
- }
-});
-openerp.base.ObjectNotFound = openerp.base.NotFound.extend( /** @lends openerp.base.ObjectNotFound# */ {
- /**
- * Thrown when an object path does not designate a valid class or object
- * in the openerp hierarchy.
- *
- * @constructs
- * @extends openerp.base.NotFound
- * @param {String} path the invalid object path
- */
- init: function (path) {
- this.path = path;
- },
- toString: function () {
- return "Could not find any object of path " + this.path;
- }
-});
-openerp.base.Registry = openerp.base.Class.extend( /** @lends openerp.base.Registry# */ {
- /**
- * Stores a mapping of arbitrary key (strings) to object paths (as strings
- * as well).
- *
- * Resolves those paths at query time in order to always fetch the correct
- * object, even if those objects have been overloaded/replaced after the
- * registry was created.
- *
- * An object path is simply a dotted name from the openerp root to the
- * object pointed to (e.g. ``"openerp.base.Session"`` for an OpenERP
- * session object).
- *
- * @constructs
- * @param {Object} mapping a mapping of keys to object-paths
- */
- init: function (mapping) {
- this.map = mapping || {};
- },
- /**
- * Retrieves the object matching the provided key string.
- *
- * @param {String} key the key to fetch the object for
- * @returns {Class} the stored class, to initialize
- *
- * @throws {openerp.base.KeyNotFound} if the object was not in the mapping
- * @throws {openerp.base.ObjectNotFound} if the object path was invalid
- */
- get_object: function (key) {
- var path_string = this.map[key];
- if (path_string === undefined) {
- throw new openerp.base.KeyNotFound(key);
- }
-
- var object_match = openerp;
- var path = path_string.split('.');
- // ignore first section
- for(var i=1; i<path.length; ++i) {
- object_match = object_match[path[i]];
-
- if (object_match === undefined) {
- throw new openerp.base.ObjectNotFound(path_string);
- }
- }
- return object_match;
- },
- /**
- * Tries a number of keys, and returns the first object matching one of
- * the keys.
- *
- * @param {Array} keys a sequence of keys to fetch the object for
- * @returns {Class} the first class found matching an object
- *
- * @throws {openerp.base.KeyNotFound} if none of the keys was in the mapping
- * @trows {openerp.base.ObjectNotFound} if a found object path was invalid
- */
- get_any: function (keys) {
- for (var i=0; i<keys.length; ++i) {
- try {
- return this.get_object(keys[i]);
- } catch (e) {
- if (e instanceof openerp.base.KeyNotFound) {
- continue;
- }
- throw e;
- }
- }
- throw new openerp.base.KeyNotFound(keys.join(','));
- },
- /**
- * Adds a new key and value to the registry.
- *
- * This method can be chained.
- *
- * @param {String} key
- * @param {String} object_path fully qualified dotted object path
- * @returns {openerp.base.Registry} itself
- */
- add: function (key, object_path) {
- this.map[key] = object_path;
- return this;
- },
- /**
- * Creates and returns a copy of the current mapping, with the provided
- * mapping argument added in (replacing existing keys if needed)
- *
- * @param {Object} [mapping={}] a mapping of keys to object-paths
- */
- clone: function (mapping) {
- return new openerp.base.Registry(
- _.extend({}, this.map, mapping || {}));
- }
-});
-
-openerp.base.CallbackEnabled = openerp.base.Class.extend({
- init: function() {
- // Transform on_* method into openerp.base.callbacks
- for (var name in this) {
- if(typeof(this[name]) == "function") {
- this[name].debug_name = name;
- // bind ALL function to this not only on_and _do ?
- if((/^on_|^do_/).test(name)) {
- this[name] = openerp.base.callback(this, this[name]);
- }
- }
- }
- }
-});
-
-openerp.base.Session = openerp.base.CallbackEnabled.extend( /** @lends openerp.base.Session# */{
- /**
- * @constructs
- * @param server
- * @param port
- */
- init: function(server, port) {
- this._super();
- this.server = (server == undefined) ? location.hostname : server;
- this.port = (port == undefined) ? location.port : port;
- this.rpc_mode = (server == location.hostname) ? "ajax" : "jsonp";
- this.debug = (window.location.search.indexOf('?debug') !== -1);
- this.db = "";
- this.login = "";
- this.password = "";
- this.user_context= {};
- this.uid = false;
- this.session_id = false;
- this.module_list = [];
- this.module_loaded = {"base": true};
- this.context = {};
- this.shortcuts = [];
- this.active_id = null;
- this.session = this;
- },
- start: function() {
- this.session_restore();
- },
- /**
- * Executes an RPC call, registering the provided callbacks.
- *
- * Registers a default error callback if none is provided, and handles
- * setting the correct session id and session context in the parameter
- * objects
- *
- * @param {String} url RPC endpoint
- * @param {Object} params call parameters
- * @param {Function} success_callback function to execute on RPC call success
- * @param {Function} error_callback function to execute on RPC call failure
- * @returns {jQuery.Deferred} jquery-provided ajax deferred
- */
- rpc: function(url, params, success_callback, error_callback) {
- var self = this;
- // Construct a JSON-RPC2 request, method is currently unused
- params.session_id = this.session_id;
-
- // Call using the rpc_mode
- var deferred = $.Deferred();
- this.rpc_ajax(url, {
- jsonrpc: "2.0",
- method: "call",
- params: params,
- id:null
- }).then(function () {deferred.resolve.apply(deferred, arguments);},
- function(error) {deferred.reject(error, $.Event());});
- return deferred.fail(function() {
- deferred.fail(function(error, event) {
- if (!event.isDefaultPrevented()) {
- self.on_rpc_error(error, event);
- }
- });
- }).then(success_callback, error_callback).promise();
- },
- /**
- * Raw JSON-RPC call
- *
- * @returns {jQuery.Deferred} ajax-based deferred object
- */
- rpc_ajax: function(url, payload) {
- var self = this;
- this.on_rpc_request();
- // url can be an $.ajax option object
- if (_.isString(url)) {
- url = {
- url: url
- }
- }
- var ajax = _.extend({
- type: "POST",
- url: url,
- dataType: 'json',
- contentType: 'application/json',
- data: JSON.stringify(payload),
- processData: false
- }, url);
- var deferred = $.Deferred();
- $.ajax(ajax).done(function(response, textStatus, jqXHR) {
- self.on_rpc_response();
- if (!response.error) {
- deferred.resolve(response["result"], textStatus, jqXHR);
- return;
- }
- if (response.error.data.type !== "session_invalid") {
- deferred.reject(response.error);
- return;
- }
- self.uid = false;
- self.on_session_invalid(function() {
- self.rpc(url, payload.params,
- function() {
- deferred.resolve.apply(deferred, arguments);
- },
- function(error, event) {
- event.preventDefault();
- deferred.reject.apply(deferred, arguments);
- });
- });
- }).fail(function(jqXHR, textStatus, errorThrown) {
- self.on_rpc_response();
- var error = {
- code: -32098,
- message: "XmlHttpRequestError " + errorThrown,
- data: {type: "xhr"+textStatus, debug: jqXHR.responseText, objects: [jqXHR, errorThrown] }
- };
- deferred.reject(error);
- });
- return deferred.promise();
- },
- on_rpc_request: function() {
- },
- on_rpc_response: function() {
- },
- on_rpc_error: function(error) {
- },
- /**
- * The session is validated either by login or by restoration of a previous session
- */
- on_session_valid: function() {
- if(!openerp._modules_loaded)
- this.load_modules();
- },
- on_session_invalid: function(contination) {
- },
- session_is_valid: function() {
- return this.uid;
- },
- session_login: function(db, login, password, success_callback) {
- var self = this;
- this.db = db;
- this.login = login;
- this.password = password;
- var params = { db: this.db, login: this.login, password: this.password };
- this.rpc("/base/session/login", params, function(result) {
- self.session_id = result.session_id;
- self.uid = result.uid;
- self.user_context = result.context;
- self.session_save();
- self.on_session_valid();
- if (success_callback)
- success_callback();
- });
- },
- session_logout: function() {
- this.uid = false;
- },
- /**
- * Reloads uid and session_id from local storage, if they exist
- */
- session_restore: function () {
- this.uid = this.get_cookie('uid');
- this.session_id = this.get_cookie('session_id');
- this.db = this.get_cookie('db');
- this.login = this.get_cookie('login');
- this.user_context = this.get_cookie("user_context");
- // we should do an rpc to confirm that this session_id is valid and if it is retrieve the information about db and login
- // then call on_session_valid
- this.on_session_valid();
- },
- /**
- * Saves the session id and uid locally
- */
- session_save: function () {
- this.set_cookie('uid', this.uid);
- this.set_cookie('session_id', this.session_id);
- this.set_cookie('db', this.db);
- this.set_cookie('login', this.login);
- this.set_cookie('user_context', this.user_context);
- },
- logout: function() {
- delete this.uid;
- delete this.session_id;
- delete this.db;
- delete this.login;
- this.set_cookie('uid', '');
- this.set_cookie('session_id', '');
- this.set_cookie('db', '');
- this.set_cookie('login', '');
- this.on_session_invalid(function() {});
- },
- /**
- * Fetches a cookie stored by an openerp session
- *
- * @private
- * @param name the cookie's name
- */
- get_cookie: function (name) {
- var nameEQ = this.element_id + '|' + name + '=';
- var cookies = document.cookie.split(';');
- for(var i=0; i<cookies.length; ++i) {
- var cookie = cookies[i].replace(/^\s*/, '');
- if(cookie.indexOf(nameEQ) === 0) {
- return JSON.parse(decodeURIComponent(cookie.substring(nameEQ.length)));
- }
- }
- return null;
- },
- /**
- * Create a new cookie with the provided name and value
- *
- * @private
- * @param name the cookie's name
- * @param value the cookie's value
- * @param ttl the cookie's time to live, 1 year by default, set to -1 to delete
- */
- set_cookie: function (name, value, ttl) {
- ttl = ttl || 24*60*60*365;
- document.cookie = [
- this.element_id + '|' + name + '=' + encodeURIComponent(JSON.stringify(value)),
- 'max-age=' + ttl,
- 'expires=' + new Date(new Date().getTime() + ttl*1000).toGMTString()
- ].join(';');
- },
- /**
- * Load additional web addons of that instance and init them
- */
- load_modules: function() {
- var self = this;
- this.rpc('/base/session/modules', {}, function(result) {
- self.module_list = result;
- var lang = self.user_context.lang;
- params = { mods: ["base"].concat(result), lang: lang};
- self.rpc('/base/webclient/translations',params).then(function(transs) {
- openerp.base._t.database.set_bundle(transs);
- var modules = self.module_list.join(',');
- var file_list = ["/base/static/lib/datejs/globalization/" +
- self.user_context.lang.replace("_", "-") + ".js",
-
- ];
- if(self.debug) {
- self.rpc('/base/webclient/csslist', {"mods": modules}, self.do_load_css);
- self.rpc('/base/webclient/jslist', {"mods": modules}, function(files) {
- self.do_load_js(file_list.concat(files));
- });
- } else {
- self.do_load_css(["/base/webclient/css?mods="+modules]);
- self.do_load_js(file_list.concat(["/base/webclient/js?mods="+modules]));
- }
- openerp._modules_loaded = true;
- });
- });
- },
- do_load_css: function (files) {
- _.each(files, function (file) {
- $('head').append($('<link>', {
- 'href': file,
- 'rel': 'stylesheet',
- 'type': 'text/css'
- }));
- });
- },
- do_load_js: function(files) {
- var self = this;
- if(files.length != 0) {
- var file = files.shift();
- var tag = document.createElement('script');
- tag.type = 'text/javascript';
- tag.src = file;
- tag.onload = tag.onreadystatechange = function() {
- if ( (tag.readyState && tag.readyState != "loaded" && tag.readyState != "complete") || tag.onload_done )
- return;
- tag.onload_done = true;
- self.do_load_js(files);
- };
- $('head').append(tag);
- self.do_load_js(files);
- } else {
- this.on_modules_loaded();
- }
- },
- on_modules_loaded: function() {
- for(var j=0; j<this.module_list.length; j++) {
- var mod = this.module_list[j];
- if(this.module_loaded[mod])
- continue;
- openerp[mod] = {};
- // init module mod
- if(openerp._openerp[mod] != undefined) {
- openerp._openerp[mod](openerp);
- this.module_loaded[mod] = true;
- }
- }
- }
-});
-
-/**
- * Utility class that any class is allowed to extend to easy common manipulations.
- *
- * It provides rpc calls, callback on all methods preceded by "on_" or "do_" and a
- * logging facility.
- */
-openerp.base.SessionAware = openerp.base.CallbackEnabled.extend({
- init: function(session) {
- this._super();
- this.session = session;
- },
- /**
- * Performs a JSON-RPC call
- *
- * @param {String} url endpoint url
- * @param {Object} data RPC parameters
- * @param {Function} success RPC call success callback
- * @param {Function} error RPC call error callback
- * @returns {jQuery.Deferred} deferred object for the RPC call
- */
- rpc: function(url, data, success, error) {
- return this.session.rpc(url, data, success, error);
- },
- log: function() {
- var args = Array.prototype.slice.call(arguments);
- var caller = arguments.callee.caller;
- // TODO add support for line number using
- // https://github.com/emwendelin/javascript-stacktrace/blob/master/stacktrace.js
- // args.unshift("" + caller.debug_name);
- this.on_log.apply(this,args);
- },
- on_log: function() {
- if(this.session.debug) {
- var notify = false;
- var body = false;
- if(window.console) {
- console.log(arguments);
- } else {
- body = true;
- }
- var a = Array.prototype.slice.call(arguments, 0);
- for(var i = 0; i < a.length; i++) {
- var v = a[i]==null ? "null" : a[i].toString();
- if(i==0) {
- notify = v.match(/^not/);
- body = v.match(/^bod/);
- }
- if(body) {
- $('<pre></pre>').text(v).appendTo($('body'));
- }
- if(notify && this.notification) {
- this.notification.notify("Logging:",v);
- }
- }
- }
- }
-});
-
-openerp.base.Widget = openerp.base.SessionAware.extend({
- /**
- * The name of the QWeb template that will be used for rendering. Must be
- * redefined in subclasses or the default render() method can not be used.
- *
- * @type string
- */
- template: null,
- /**
- * The prefix used to generate an id automatically. Should be redefined in
- * subclasses. If it is not defined, a generic identifier will be used.
- *
- * @type string
- */
- identifier_prefix: 'generic-identifier-',
- /**
- * Construct the widget and set its parent if a parent is given.
- *
- * @constructs
- * @param {openerp.base.Widget} parent Binds the current instance to the given Widget instance.
- * When that widget is destroyed by calling stop(), the current instance will be
- * destroyed too. Can be null.
- * @param {String} element_id Deprecated. Sets the element_id. Only useful when you want
- * to bind the current Widget to an already existing part of the DOM, which is not compatible
- * with the DOM insertion methods provided by the current implementation of Widget. So
- * for new components this argument should not be provided any more.
- */
- init: function(parent, /** @deprecated */ element_id) {
- this._super((parent || {}).session);
- // if given an element_id, try to get the associated DOM element and save
- // a reference in this.$element. Else just generate a unique identifier.
- this.element_id = element_id;
- this.element_id = this.element_id || _.uniqueId(this.identifier_prefix);
- var tmp = document.getElementById(this.element_id);
- this.$element = tmp ? $(tmp) : undefined;
-
- this.widget_parent = parent;
- this.widget_children = [];
- if(parent && parent.widget_children) {
- parent.widget_children.push(this);
- }
- // useful to know if the widget was destroyed and should not be used anymore
- this.widget_is_stopped = false;
- },
- /**
- * Render the current widget and appends it to the given jQuery object or Widget.
- *
- * @param target A jQuery object or a Widget instance.
- */
- appendTo: function(target) {
- var self = this;
- return this._render_and_insert(function(t) {
- self.$element.appendTo(t);
- }, target);
- },
- /**
- * Render the current widget and prepends it to the given jQuery object or Widget.
- *
- * @param target A jQuery object or a Widget instance.
- */
- prependTo: function(target) {
- var self = this;
- return this._render_and_insert(function(t) {
- self.$element.prependTo(t);
- }, target);
- },
- /**
- * Render the current widget and inserts it after to the given jQuery object or Widget.
- *
- * @param target A jQuery object or a Widget instance.
- */
- insertAfter: function(target) {
- var self = this;
- return this._render_and_insert(function(t) {
- self.$element.insertAfter(t);
- }, target);
- },
- /**
- * Render the current widget and inserts it before to the given jQuery object or Widget.
- *
- * @param target A jQuery object or a Widget instance.
- */
- insertBefore: function(target) {
- var self = this;
- return this._render_and_insert(function(t) {
- self.$element.insertBefore(t);
- }, target);
- },
- _render_and_insert: function(insertion, target) {
- var rendered = this.render();
- this.$element = $(rendered);
- if (target instanceof openerp.base.Widget)
- target = target.$element;
- insertion(target);
- return this.start();
- },
- /**
- * Renders the widget using QWeb, `this.template` must be defined.
- * The context given to QWeb contains the "widget" key that references `this`.
- *
- * @param {Object} additional Additional context arguments to pass to the template.
- */
- render: function (additional) {
- return QWeb.render(this.template, _.extend({widget: this}, additional || {}));
- },
- /**
- * Method called after rendering. Mostly used to bind actions, perform asynchronous
- * calls, etc...
- *
- * By convention, the method should return a promise to inform the caller when
- * this widget has been initialized.
- *
- * @returns {jQuery.Deferred}
- */
- start: function() {
- if (!this.$element) {
- var tmp = document.getElementById(this.element_id);
- this.$element = tmp ? $(tmp) : undefined;
- }
- return $.Deferred().done().promise();
- },
- /**
- * Destroys the current widget, also destory all its children before destroying itself.
- */
- stop: function() {
- _.each(_.clone(this.widget_children), function(el) {
- el.stop();
- });
- if(this.$element != null) {
- this.$element.remove();
- }
- if (this.widget_parent && this.widget_parent.widget_children) {
- this.widget_parent.widget_children = _.without(this.widget_parent.widget_children, this);
- }
- this.widget_parent = null;
- this.widget_is_stopped = true;
- },
- /**
- * Inform the action manager to do an action. Of course, this suppose that
- * the action manager can be found amongst the ancestors of the current widget.
- * If that's not the case this method will simply return `false`.
- */
- do_action: function(action, on_finished) {
- if (this.widget_parent) {
- return this.widget_parent.do_action(action, on_finished);
- }
- return false;
- },
- do_notify: function() {
- if (this.widget_parent) {
- return this.widget_parent.do_notify.apply(this,arguments);
- }
- return false;
- },
- do_warn: function() {
- if (this.widget_parent) {
- return this.widget_parent.do_warn.apply(this,arguments);
- }
- return false;
- },
- rpc: function(url, data, success, error) {
- var def = $.Deferred().then(success, error);
- var self = this;
- this._super(url, data). then(function() {
- if (!self.widget_is_stopped)
- def.resolve.apply(def, arguments);
- }, function() {
- if (!self.widget_is_stopped)
- def.reject.apply(def, arguments);
- });
- return def.promise();
- }
-});
-
-/**
- * @deprecated
- * For retro compatibility only, the only difference with is that render() uses
- * directly `this` instead of context with a "widget" key.
- */
-openerp.base.OldWidget = openerp.base.Widget.extend({
- render: function (additional) {
- return QWeb.render(this.template, _.extend(_.extend({}, this), additional || {}));
- }
-});
-
-openerp.base.TranslationDataBase = openerp.base.Class.extend({
- init: function() {
- this.db = {};
- this.parameters = {"direction": 'ltr',
- "date_format": '%m/%d/%Y',
- "time_format": '%H:%M:%S',
- "grouping": "[]",
- "decimal_point": ".",
- "thousands_sep": ","};
- },
- set_bundle: function(translation_bundle) {
- var self = this;
- this.db = {};
- var modules = _.keys(translation_bundle.modules).sort();
- if (_.include(modules, "base")) {
- modules = ["base"].concat(_.without(modules, "base"));
- }
- _.each(modules, function(name) {
- self.add_module_translation(translation_bundle.modules[name]);
- });
- if (translation_bundle.lang_parameters) {
- this.parameters = translation_bundle.lang_parameters;
- }
- },
- add_module_translation: function(mod) {
- var self = this;
- _.each(mod.messages, function(message) {
- if (self.db[message.id] === undefined) {
- self.db[message.id] = message.string;
- }
- });
- },
- build_translation_function: function() {
- var self = this;
- var fcnt = function(str) {
- var tmp = self.get(str);
- return tmp === undefined ? str : tmp;
- }
- fcnt.database = this;
- return fcnt;
- },
- get: function(key) {
- if (this.db[key])
- return this.db[key];
- return undefined;
- }
-});
-
-openerp.base._t = new openerp.base.TranslationDataBase().build_translation_function();
-
-};
-
-// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
diff --git a/addons/base/static/src/js/data.js b/addons/base/static/src/js/data.js
deleted file mode 100644
index e95adaf8870..00000000000
--- a/addons/base/static/src/js/data.js
+++ /dev/null
@@ -1,787 +0,0 @@
-
-openerp.base.data = function(openerp) {
-
-/**
- * Serializes the sort criterion array of a dataset into a form which can be
- * consumed by OpenERP's RPC APIs.
- *
- * @param {Array} criterion array of fields, from first to last criteria, prefixed with '-' for reverse sorting
- * @returns {String} SQL-like sorting string (``ORDER BY``) clause
- */
-openerp.base.serialize_sort = function (criterion) {
- return _.map(criterion,
- function (criteria) {
- if (criteria[0] === '-') {
- return criteria.slice(1) + ' DESC';
- }
- return criteria + ' ASC';
- }).join(', ');
-};
-
-openerp.base.DataGroup = openerp.base.Widget.extend( /** @lends openerp.base.DataGroup# */{
- /**
- * Management interface between views and grouped collections of OpenERP
- * records.
- *
- * The root DataGroup is instantiated with the relevant information
- * (a session, a model, a domain, a context and a group_by sequence), the
- * domain and context may be empty. It is then interacted with via
- * :js:func:`~openerp.base.DataGroup.list`, which is used to read the
- * content of the current grouping level.
- *
- * @constructs
- * @extends openerp.base.Widget
- *
- * @param {openerp.base.Session} session Current OpenERP session
- * @param {String} model name of the model managed by this DataGroup
- * @param {Array} domain search domain for this DataGroup
- * @param {Object} context context of the DataGroup's searches
- * @param {Array} group_by sequence of fields by which to group
- * @param {Number} [level=0] nesting level of the group
- */
- init: function(parent, model, domain, context, group_by, level) {
- this._super(parent, null);
- if (group_by) {
- if (group_by.length || context['group_by_no_leaf']) {
- return new openerp.base.ContainerDataGroup( this, model, domain, context, group_by, level);
- } else {
- return new openerp.base.GrouplessDataGroup( this, model, domain, context, level);
- }
- }
-
- this.model = model;
- this.context = context;
- this.domain = domain;
-
- this.level = level || 0;
- },
- cls: 'DataGroup'
-});
-openerp.base.ContainerDataGroup = openerp.base.DataGroup.extend( /** @lends openerp.base.ContainerDataGroup# */ {
- /**
- *
- * @constructs
- * @extends openerp.base.DataGroup
- *
- * @param session
- * @param model
- * @param domain
- * @param context
- * @param group_by
- * @param level
- */
- init: function (parent, model, domain, context, group_by, level) {
- this._super(parent, model, domain, context, null, level);
-
- this.group_by = group_by;
- },
- /**
- * The format returned by ``read_group`` is absolutely dreadful:
- *
- * * A ``__context`` key provides future grouping levels
- * * A ``__domain`` key provides the domain for the next search
- * * The current grouping value is provided through the name of the
- * current grouping name e.g. if currently grouping on ``user_id``, then
- * the ``user_id`` value for this group will be provided through the
- * ``user_id`` key.
- * * Similarly, the number of items in the group (not necessarily direct)
- * is provided via ``${current_field}_count``
- * * Other aggregate fields are just dumped there
- *
- * This function slightly improves the grouping records by:
- *
- * * Adding a ``grouped_on`` property providing the current grouping field
- * * Adding a ``value`` and a ``length`` properties which replace the
- * ``$current_field`` and ``${current_field}_count`` ones
- * * Moving aggregate values into an ``aggregates`` property object
- *
- * Context and domain keys remain as-is, they should not be used externally
- * but in case they're needed...
- *
- * @param {Object} group ``read_group`` record
- */
- transform_group: function (group) {
- var field_name = this.group_by[0];
- // In cases where group_by_no_leaf and no group_by, the result of
- // read_group has aggregate fields but no __context or __domain.
- // Create default (empty) values for those so that things don't break
- var fixed_group = _.extend(
- {__context: {group_by: []}, __domain: []},
- group);
-
- var aggregates = {};
- _(fixed_group).each(function (value, key) {
- if (key.indexOf('__') === 0
- || key === field_name
- || key === field_name + '_count') {
- return;
- }
- aggregates[key] = value || 0;
- });
-
- return {
- __context: fixed_group.__context,
- __domain: fixed_group.__domain,
-
- grouped_on: field_name,
- // if terminal group (or no group) and group_by_no_leaf => use group.__count
- length: fixed_group[field_name + '_count'] || fixed_group.__count,
- value: fixed_group[field_name],
-
- openable: !(this.context['group_by_no_leaf']
- && fixed_group.__context.group_by.length === 0),
-
- aggregates: aggregates
- };
- },
- fetch: function (fields) {
- // internal method
- var d = new $.Deferred();
- var self = this;
-
- this.rpc('/base/group/read', {
- model: this.model,
- context: this.context,
- domain: this.domain,
- fields: _.uniq(this.group_by.concat(fields)),
- group_by_fields: this.group_by,
- sort: openerp.base.serialize_sort(this.sort)
- }, function () { }).then(function (response) {
- var data_groups = _(response).map(
- _.bind(self.transform_group, self));
- self.groups = data_groups;
- d.resolveWith(self, [data_groups]);
- }, function () {
- d.rejectWith.apply(d, [self, arguments]);
- });
- return d.promise();
- },
- /**
- * The items of a list have the following properties:
- *
- * ``length``
- * the number of records contained in the group (and all of its
- * sub-groups). This does *not* provide the size of the "next level"
- * of the group, unless the group is terminal (no more groups within
- * it).
- * ``grouped_on``
- * the name of the field this level was grouped on, this is mostly
- * used for display purposes, in order to know the name of the current
- * level of grouping. The ``grouped_on`` should be the same for all
- * objects of the list.
- * ``value``
- * the value which led to this group (this is the value all contained
- * records have for the current ``grouped_on`` field name).
- * ``aggregates``
- * a mapping of other aggregation fields provided by ``read_group``
- *
- * @param {Array} fields the list of fields to aggregate in each group, can be empty
- * @param {Function} ifGroups function executed if any group is found (DataGroup.group_by is non-null and non-empty), called with a (potentially empty) list of groups as parameters.
- * @param {Function} ifRecords function executed if there is no grouping left to perform, called with a DataSet instance as parameter
- */
- list: function (fields, ifGroups, ifRecords) {
- var self = this;
- this.fetch(fields).then(function (group_records) {
- ifGroups(_(group_records).map(function (group) {
- var child_context = _.extend({}, self.context, group.__context);
- return _.extend(
- new openerp.base.DataGroup(
- self, self.model, group.__domain,
- child_context, child_context.group_by,
- self.level + 1),
- group, {sort: self.sort});
- }));
- });
- }
-});
-openerp.base.GrouplessDataGroup = openerp.base.DataGroup.extend( /** @lends openerp.base.GrouplessDataGroup# */ {
- /**
- *
- * @constructs
- * @extends openerp.base.DataGroup
- *
- * @param session
- * @param model
- * @param domain
- * @param context
- * @param level
- */
- init: function (parent, model, domain, context, level) {
- this._super(parent, model, domain, context, null, level);
- },
- list: function (fields, ifGroups, ifRecords) {
- ifRecords(_.extend(
- new openerp.base.DataSetSearch(this, this.model),
- {domain: this.domain, context: this.context, _sort: this.sort}));
- }
-});
-openerp.base.StaticDataGroup = openerp.base.GrouplessDataGroup.extend( /** @lends openerp.base.StaticDataGroup# */ {
- /**
- * A specialization of groupless data groups, relying on a single static
- * dataset as its records provider.
- *
- * @constructs
- * @extends openerp.base.GrouplessDataGroup
- * @param {openep.base.DataSetStatic} dataset a static dataset backing the groups
- */
- init: function (dataset) {
- this.dataset = dataset;
- },
- list: function (fields, ifGroups, ifRecords) {
- ifRecords(this.dataset);
- }
-});
-
-openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.DataSet# */{
- /**
- * DateaManagement interface between views and the collection of selected
- * OpenERP records (represents the view's state?)
- *
- * @constructs
- * @extends openerp.base.Widget
- *
- * @param {String} model the OpenERP model this dataset will manage
- */
- init: function(source_controller, model, context) {
- // we don't want the dataset to be a child of anything!
- this._super(null);
- this.session = source_controller ? source_controller.session : undefined;
- this.model = model;
- this.context = context || {};
- this.index = null;
- },
- start: function() {
- },
- previous: function () {
- this.index -= 1;
- if (this.index < 0) {
- this.index = this.ids.length - 1;
- }
- return this;
- },
- next: function () {
- this.index += 1;
- if (this.index >= this.ids.length) {
- this.index = 0;
- }
- return this;
- },
- /**
- * Read records.
- *
- * @param {Array} ids identifiers of the records to read
- * @param {Array} fields fields to read and return, by default all fields are returned
- * @param {Function} callback function called with read result
- * @returns {$.Deferred}
- */
- read_ids: function (ids, fields, callback) {
- return this.rpc('/base/dataset/get', {
- model: this.model,
- ids: ids,
- fields: fields,
- context: this.get_context()
- }, callback);
- },
- /**
- * Read a slice of the records represented by this DataSet, based on its
- * domain and context.
- *
- * @param {Array} [fields] fields to read and return, by default all fields are returned
- * @params {Object} options
- * @param {Number} [options.offset=0] The index from which selected records should be returned
- * @param {Number} [options.limit=null] The maximum number of records to return
- * @param {Function} callback function called with read_slice result
- * @returns {$.Deferred}
- */
- read_slice: function (fields, options, callback) {
- return null;
- },
- /**
- * Reads the current dataset record (from its index)
- *
- * @params {Array} [fields] fields to read and return, by default all fields are returned
- * @params {Function} callback function called with read_index result
- * @returns {$.Deferred}
- */
- read_index: function (fields, callback) {
- var def = $.Deferred().then(callback);
- if (_.isEmpty(this.ids)) {
- def.reject();
- } else {
- fields = fields || false;
- return this.read_ids([this.ids[this.index]], fields).then(function(records) {
- def.resolve(records[0]);
- }, function() {
- def.reject.apply(def, arguments);
- });
- }
- return def.promise();
- },
- /**
- * Reads default values for the current model
- *
- * @param {Array} [fields] fields to get default values for, by default all defaults are read
- * @param {Function} callback function called with default_get result
- * @returns {$.Deferred}
- */
- default_get: function(fields, callback) {
- return this.rpc('/base/dataset/default_get', {
- model: this.model,
- fields: fields,
- context: this.get_context()
- }, callback);
- },
- /**
- * Creates a new record in db
- *
- * @param {Object} data field values to set on the new record
- * @param {Function} callback function called with operation result
- * @param {Function} error_callback function called in case of creation error
- * @returns {$.Deferred}
- */
- create: function(data, callback, error_callback) {
- return this.rpc('/base/dataset/create', {
- model: this.model,
- data: data,
- context: this.get_context()
- }, callback, error_callback);
- },
- /**
- * Saves the provided data in an existing db record
- *
- * @param {Number|String} id identifier for the record to alter
- * @param {Object} data field values to write into the record
- * @param {Function} callback function called with operation result
- * @param {Function} error_callback function called in case of write error
- * @returns {$.Deferred}
- */
- write: function (id, data, options, callback, error_callback) {
- var options = options || {};
- return this.rpc('/base/dataset/save', {
- model: this.model,
- id: id,
- data: data,
- context: this.get_context(options.context)
- }, callback, error_callback);
- },
- /**
- * Deletes an existing record from the database
- *
- * @param {Number|String} ids identifier of the record to delete
- * @param {Function} callback function called with operation result
- * @param {Function} error_callback function called in case of deletion error
- */
- unlink: function(ids, callback, error_callback) {
- var self = this;
- return this.call_and_eval("unlink", [ids, this.get_context()], null, 1,
- callback, error_callback);
- },
- /**
- * Calls an arbitrary RPC method
- *
- * @param {String} method name of the method (on the current model) to call
- * @param {Array} [args] arguments to pass to the method
- * @param {Function} callback
- * @param {Function} error_callback
- * @returns {$.Deferred}
- */
- call: function (method, args, callback, error_callback) {
- return this.rpc('/base/dataset/call', {
- model: this.model,
- method: method,
- args: args || []
- }, callback, error_callback);
- },
- /**
- * Calls an arbitrary method, with more crazy
- *
- * @param {String} method
- * @param {Array} [args]
- * @param {Number} [domain_index] index of a domain to evaluate in the args array
- * @param {Number} [context_index] index of a context to evaluate in the args array
- * @param {Function} callback
- * @param {Function }error_callback
- * @returns {$.Deferred}
- */
- call_and_eval: function (method, args, domain_index, context_index, callback, error_callback) {
- return this.rpc('/base/dataset/call', {
- model: this.model,
- method: method,
- domain_id: domain_index || null,
- context_id: context_index || null,
- args: args || []
- }, callback, error_callback);
- },
- /**
- * Calls a button method, usually returning some sort of action
- *
- * @param {String} method
- * @param {Array} [args]
- * @param {Function} callback
- * @param {Function} error_callback
- * @returns {$.Deferred}
- */
- call_button: function (method, args, callback, error_callback) {
- return this.rpc('/base/dataset/call_button', {
- model: this.model,
- method: method,
- domain_id: null,
- context_id: 1,
- args: args || []
- }, callback, error_callback);
- },
- /**
- * Fetches the "readable name" for records, based on intrinsic rules
- *
- * @param {Array} ids
- * @param {Function} callback
- * @returns {$.Deferred}
- */
- name_get: function(ids, callback) {
- return this.call_and_eval('name_get', [ids, this.get_context()], null, 1, callback);
- },
- /**
- *
- * @param {String} name name to perform a search for/on
- * @param {Array} [domain=[]] filters for the objects returned, OpenERP domain
- * @param {String} [operator='ilike'] matching operator to use with the provided name value
- * @param {Number} [limit=100] maximum number of matches to return
- * @param {Function} callback function to call with name_search result
- * @returns {$.Deferred}
- */
- name_search: function (name, domain, operator, limit, callback) {
- return this.call_and_eval('name_search',
- [name || '', domain || false, operator || 'ilike', this.get_context(), limit || 100],
- 1, 3, callback);
- },
- /**
- * @param name
- * @param callback
- */
- name_create: function(name, callback) {
- return this.call_and_eval('name_create', [name, this.get_context()], null, 1, callback);
- },
- exec_workflow: function (id, signal, callback) {
- return this.rpc('/base/dataset/exec_workflow', {
- model: this.model,
- id: id,
- signal: signal
- }, callback);
- },
- get_context: function(request_context) {
- if (request_context) {
- return new openerp.base.CompoundContext(this.context, request_context);
- }
- return this.context;
- }
-});
-openerp.base.DataSetStatic = openerp.base.DataSet.extend({
- init: function(parent, model, context, ids) {
- this._super(parent, model, context);
- // all local records
- this.ids = ids || [];
- },
- read_slice: function (fields, options, callback) {
- // TODO remove fields from options
- var self = this,
- offset = options.offset || 0,
- limit = options.limit || false,
- fields = fields || false;
- var end_pos = limit && limit !== -1 ? offset + limit : undefined;
- return this.read_ids(this.ids.slice(offset, end_pos), fields, callback);
- },
- set_ids: function (ids) {
- this.ids = ids;
- if (this.index !== null) {
- this.index = this.index <= this.ids.length - 1 ?
- this.index : (this.ids.length > 0 ? this.length - 1 : 0);
- }
- },
- unlink: function(ids) {
- this.on_unlink(ids);
- return $.Deferred().resolve({result: true});
- },
- on_unlink: function(ids) {
- this.set_ids(_.without.apply(null, [this.ids].concat(ids)));
- }
-});
-openerp.base.DataSetSearch = openerp.base.DataSet.extend({
- /**
- * @constructs
- *
- * @param {Object} parent
- * @param {String} model
- * @param {Object} context
- * @param {Array} domain
- */
- init: function(parent, model, context, domain) {
- this._super(parent, model, context);
- this.domain = domain || [];
- this._sort = [];
- this.offset = 0;
- // subset records[offset:offset+limit]
- // is it necessary ?
- this.ids = [];
- },
- /**
- * Read a slice of the records represented by this DataSet, based on its
- * domain and context.
- *
- * @params {Object} options
- * @param {Array} [options.fields] fields to read and return, by default all fields are returned
- * @param {Object} [options.context] context data to add to the request payload, on top of the DataSet's own context
- * @param {Array} [options.domain] domain data to add to the request payload, ANDed with the dataset's domain
- * @param {Number} [options.offset=0] The index from which selected records should be returned
- * @param {Number} [options.limit=null] The maximum number of records to return
- * @param {Function} callback function called with read_slice result
- * @returns {$.Deferred}
- */
- read_slice: function (fields, options, callback) {
- var self = this;
- var options = options || {};
- var offset = options.offset || 0;
- return this.rpc('/base/dataset/search_read', {
- model: this.model,
- fields: fields || false,
- domain: this.get_domain(options.domain),
- context: this.get_context(options.context),
- sort: this.sort(),
- offset: offset,
- limit: options.limit || false
- }, function (result) {
- self.ids = result.ids;
- self.offset = offset;
- if (callback) {
- callback(result.records);
- }
- });
- },
- get_domain: function (other_domain) {
- if (other_domain) {
- return new openerp.base.CompoundDomain(this.domain, other_domain);
- }
- return this.domain;
- },
- /**
- * Reads or changes sort criteria on the dataset.
- *
- * If not provided with any argument, serializes the sort criteria to
- * an SQL-like form usable by OpenERP's ORM.
- *
- * If given a field, will set that field as first sorting criteria or,
- * if the field is already the first sorting criteria, will reverse it.
- *
- * @param {String} [field] field to sort on, reverses it (toggle from ASC to DESC) if already the main sort criteria
- * @param {Boolean} [force_reverse=false] forces inserting the field as DESC
- * @returns {String|undefined}
- */
- sort: function (field, force_reverse) {
- if (!field) {
- return openerp.base.serialize_sort(this._sort);
- }
- var reverse = force_reverse || (this._sort[0] === field);
- this._sort.splice.apply(
- this._sort, [0, this._sort.length].concat(
- _.without(this._sort, field, '-' + field)));
-
- this._sort.unshift((reverse ? '-' : '') + field);
- return undefined;
- },
- unlink: function(ids, callback, error_callback) {
- var self = this;
- return this._super(ids, function(result) {
- self.ids = _.without.apply(_, [self.ids].concat(ids));
- if (this.index !== null) {
- self.index = self.index <= self.ids.length - 1 ?
- self.index : (self.ids.length > 0 ? self.ids.length -1 : 0);
- }
- if (callback)
- callback(result);
- }, error_callback);
- }
-});
-openerp.base.BufferedDataSet = openerp.base.DataSetStatic.extend({
- virtual_id_prefix: "one2many_v_id_",
- virtual_id_regex: /one2many_v_id_.*/,
- debug_mode: true,
- init: function() {
- this._super.apply(this, arguments);
- this.reset_ids([]);
- },
- create: function(data, callback, error_callback) {
- var cached = {id:_.uniqueId(this.virtual_id_prefix), values: data};
- this.to_create.push(cached);
- this.cache.push(cached);
- var to_return = $.Deferred().then(callback);
- to_return.resolve({result: cached.id});
- return to_return.promise();
- },
- write: function (id, data, callback) {
- var self = this;
- var record = _.detect(this.to_create, function(x) {return x.id === id;});
- record = record || _.detect(this.to_write, function(x) {return x.id === id;});
- var dirty = false;
- if (record) {
- for (k in data) {
- if (record.values[k] === undefined || record.values[k] !== data[k]) {
- dirty = true;
- break;
- }
- }
- $.extend(record.values, data);
- } else {
- dirty = true;
- record = {id: id, values: data};
- self.to_write.push(record);
- }
- var cached = _.detect(this.cache, function(x) {return x.id === id;});
- $.extend(cached.values, record.values);
- if (dirty)
- this.on_change();
- var to_return = $.Deferred().then(callback);
- to_return.resolve({result: true});
- return to_return.promise();
- },
- unlink: function(ids, callback, error_callback) {
- var self = this;
- _.each(ids, function(id) {
- if (! _.detect(self.to_create, function(x) { return x.id === id; })) {
- self.to_delete.push({id: id})
- }
- });
- this.to_create = _.reject(this.to_create, function(x) { return _.include(ids, x.id);});
- this.to_write = _.reject(this.to_write, function(x) { return _.include(ids, x.id);});
- this.cache = _.reject(this.cache, function(x) { return _.include(ids, x.id);});
- this.set_ids(_.without.apply(_, [this.ids].concat(ids)));
- this.on_change();
- var to_return = $.Deferred().then(callback);
- setTimeout(function () {to_return.resolve({result: true});}, 0);
- return to_return.promise();
- },
- reset_ids: function(ids) {
- this.set_ids(ids);
- this.to_delete = [];
- this.to_create = [];
- this.to_write = [];
- this.cache = [];
- this.delete_all = false;
- },
- on_change: function() {},
- read_ids: function (ids, fields, callback) {
- var self = this;
- var to_get = [];
- _.each(ids, function(id) {
- var cached = _.detect(self.cache, function(x) {return x.id === id;});
- var created = _.detect(self.to_create, function(x) {return x.id === id;});
- if (created) {
- _.each(fields, function(x) {if (cached.values[x] === undefined) cached.values[x] = false;});
- } else {
- if (!cached || !_.all(fields, function(x) {return cached.values[x] !== undefined}))
- to_get.push(id);
- }
- });
- var completion = $.Deferred().then(callback);
- var return_records = function() {
- var records = _.map(ids, function(id) {
- return _.extend({}, _.detect(self.cache, function(c) {return c.id === id;}).values, {"id": id});
- });
- if (self.debug_mode) {
- if (_.include(records, undefined)) {
- throw "Record not correctly loaded";
- }
- }
- setTimeout(function () {completion.resolve(records);}, 0);
- }
- if(to_get.length > 0) {
- var rpc_promise = this._super(to_get, fields, function(records) {
- _.each(records, function(record, index) {
- var id = to_get[index];
- var cached = _.detect(self.cache, function(x) {return x.id === id;});
- if (!cached) {
- self.cache.push({id: id, values: record});
- } else {
- // I assume cache value is prioritary
- _.defaults(cached.values, record);
- }
- });
- return_records();
- });
- $.when(rpc_promise).fail(function() {completion.reject();});
- } else {
- return_records();
- }
- return completion.promise();
- }
-});
-openerp.base.ReadOnlyDataSetSearch = openerp.base.DataSetSearch.extend({
- create: function(data, callback, error_callback) {
- this.on_create(data);
- var to_return = $.Deferred().then(callback);
- setTimeout(function () {to_return.resolve({"result": undefined});}, 0);
- return to_return.promise();
- },
- on_create: function(data) {},
- write: function (id, data, callback) {
- this.on_write(id, data);
- var to_return = $.Deferred().then(callback);
- setTimeout(function () {to_return.resolve({"result": true});}, 0);
- return to_return.promise();
- },
- on_write: function(id, data) {},
- unlink: function(ids, callback, error_callback) {
- this.on_unlink(ids);
- var to_return = $.Deferred().then(callback);
- setTimeout(function () {to_return.resolve({"result": true});}, 0);
- return to_return.promise();
- },
- on_unlink: function(ids) {}
-});
-
-openerp.base.CompoundContext = openerp.base.Class.extend({
- init: function () {
- this.__ref = "compound_context";
- this.__contexts = [];
- this.__eval_context = null;
- var self = this;
- _.each(arguments, function(x) {
- self.add(x);
- });
- },
- add: function (context) {
- this.__contexts.push(context);
- return this;
- },
- set_eval_context: function (eval_context) {
- this.__eval_context = eval_context;
- return this;
- },
- get_eval_context: function () {
- return this.__eval_context;
- }
-});
-
-openerp.base.CompoundDomain = openerp.base.Class.extend({
- init: function () {
- this.__ref = "compound_domain";
- this.__domains = [];
- this.__eval_context = null;
- var self = this;
- _.each(arguments, function(x) {
- self.add(x);
- });
- },
- add: function(domain) {
- this.__domains.push(domain);
- return this;
- },
- set_eval_context: function(eval_context) {
- this.__eval_context = eval_context;
- return this;
- },
- get_eval_context: function() {
- return this.__eval_context;
- }
-});
-};
-
-// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
diff --git a/addons/base/static/src/js/data_export.js b/addons/base/static/src/js/data_export.js
deleted file mode 100644
index ad440302c69..00000000000
--- a/addons/base/static/src/js/data_export.js
+++ /dev/null
@@ -1,402 +0,0 @@
-openerp.base.data_export = function(openerp) {
-openerp.base.DataExport = openerp.base.Dialog.extend({
- init: function(parent, dataset) {
- this._super(parent);
- this.dataset = dataset;
- },
- start: function() {
- var self = this;
- self._super(false);
- self.template = 'ExportTreeView';
- self.dialog_title = "Export Data";
- self.open({
- modal: true,
- width: '55%',
- height: 'auto',
- position: 'top',
- buttons : {
- "Close" : function() {
- self.close();
- },
- "Export To File" : function() {
- self.on_click_export_data();
- }
- },
- close: function(event, ui){ self.close();}
- });
- self.on_show_exists_export_list();
- self.$element.removeClass('ui-dialog-content ui-widget-content');
- self.$element.find('#add_field').click(function() {
- if ($('#field-tree-structure tr.ui-selected')) {
- var fld = self.$element.find('#field-tree-structure tr.ui-selected').find('a');
- for (var i = 0; i < fld.length; i++) {
- var id = $(fld[i]).attr('id').split('-')[1];
- var string = $(fld[i]).attr('string');
- self.add_field(id, string);
- }
- self.$element.find('#field-tree-structure tr').removeClass('ui-selected');
- }
- });
- self.$element.find('#remove_field').click(function() {
- self.$element.find('#fields_list option:selected').remove();
- });
- self.$element.find('#remove_all_field').click(function() {
- self.$element.find('#fields_list option').remove();
- });
- self.$element.find('#export_new_list').click(function() {
- self.on_show_save_list();
- });
- var import_comp = self.$element.find('#import_compat option:selected').val(),
- params = {
- import_compat: parseInt(import_comp)
- };
- self.rpc('/base/export/get_fields', { model: self.dataset.model, params: params }, self.on_show_data);
-
- self.$element.find('#import_compat').change(function() {
- self.$element.find('#fields_list option').remove();
- self.$element.find('#field-tree-structure').remove();
- var import_comp = self.$element.find("#import_compat option:selected").val();
- if (import_comp) {
- var params = {
- import_compat: parseInt(import_comp)
- }
- self.rpc("/base/export/get_fields", { model: self.dataset.model, params: params}, self.on_show_data);
- }
- });
- },
- on_show_exists_export_list: function() {
- var self = this;
- if (self.$element.find('#saved_export_list').is(':hidden')) {
- self.$element.find('#ExistsExportList').show();
- } else {
- this.rpc('/base/export/exist_export_lists', { 'model': this.dataset.model}, function(export_list) {
- if (export_list.length) {
- self.$element.find('#ExistsExportList').append(QWeb.render('Exists.ExportList', {'existing_exports': export_list}));
- self.$element.find('#saved_export_list').change(function() {
- self.$element.find('#fields_list option').remove();
- var export_id = self.$element.find('#saved_export_list option:selected').val();
- if (export_id) {
- self.rpc('/base/export/namelist', {'model': self.dataset.model, export_id: parseInt(export_id)}, self.do_load_export_field);
- }
- });
- self.$element.find('#delete_export_list').click(function() {
- var select_exp = self.$element.find('#saved_export_list option:selected');
- if (select_exp.val()) {
- self.rpc('/base/export/delete_export', { export_id: parseInt(select_exp.val())}, {});
- select_exp.remove();
- if (self.$element.find('#saved_export_list option').length <= 1) {
- self.$element.find('#ExistsExportList').hide();
- }
- }
- });
- }
- });
- }
- },
- do_load_export_field: function(field_list) {
- var export_node = this.$element.find("#fields_list");
- for (var key in field_list) {
- export_node.append(new Option(field_list[key], key));
- }
- },
- on_show_save_list: function() {
- var self = this;
- var current_node = self.$element.find("#savenewlist");
- if (!(current_node.find("label")).length) {
- current_node.append(QWeb.render('ExportNewList'));
- current_node.find("#add_export_list").click(function() {
- var value = current_node.find("#savelist_name").val();
- if (value) {
- self.do_save_export_list(value);
- } else {
- alert("Pleae Enter Save Field List Name");
- }
- });
- } else {
- if (current_node.is(':hidden')) {
- current_node.show();
- current_node.find("#savelist_name").val("");
- } else {
- current_node.hide();
- }
- }
- },
- do_save_export_list: function(value) {
- var self = this;
- var export_field = self.get_fields();
- if (export_field.length) {
- self.rpc("/base/export/save_export_lists", {"model": self.dataset.model, "name":value, "field_list":export_field}, function(exp_id) {
- if (exp_id) {
- if (self.$element.find("#saved_export_list").length > 0) {
- self.$element.find("#saved_export_list").append(new Option(value, exp_id));
- } else {
- self.on_show_exists_export_list();
- }
- if (self.$element.find("#saved_export_list").is(":hidden")) {
- self.on_show_exists_export_list();
- }
- }
- });
- self.on_show_save_list();
- self.$element.find("#fields_list option").remove();
- }
- },
- on_click: function(id, result) {
- var self = this;
- self.field_id = id.split("-")[1];
- var is_loaded = 0;
- _.each(result, function(record) {
- if (record['id'] == self.field_id && (record['children']).length >= 1) {
- var model = record['params']['model'],
- prefix = record['params']['prefix'],
- name = record['params']['name'];
- $(record['children']).each(function(e, childid) {
- if (self.$element.find("tr[id='treerow-" + childid + "']").length > 0) {
- if (self.$element.find("tr[id='treerow-" + childid + "']").is(':hidden')) {
- is_loaded = -1;
- } else {
- is_loaded++;
- }
- }
- });
- if (is_loaded == 0) {
- if (self.$element.find("tr[id='treerow-" + self.field_id +"']").find('img').attr('src') === '/base/static/src/img/expand.gif') {
- if (model) {
- var import_comp = self.$element.find("#import_compat option:selected").val();
- var params = {
- import_compat: parseInt(import_comp),
- parent_field_type : record['field_type']
- }
- self.rpc("/base/export/get_fields", {
- model: model,
- prefix: prefix,
- name: name,
- field_parent : self.field_id,
- params: params
- }, function(results) {
- self.on_show_data(results);
- });
- }
- }
- } else if (is_loaded > 0) {
- self.showcontent(self.field_id, true);
- } else {
- self.showcontent(self.field_id, false);
- }
- }
- });
- },
- on_show_data: function(result) {
- var self = this;
- var imp_cmpt = parseInt(self.$element.find("#import_compat option:selected").val());
- var current_tr = self.$element.find("tr[id='treerow-" + self.field_id + "']");
- if (current_tr.length >= 1) {
- current_tr.find('img').attr('src','/base/static/src/img/collapse.gif');
- current_tr.after(QWeb.render('ExportTreeView-Secondary.children', {'fields': result}));
- } else {
- self.$element.find('#left_field_panel').append(QWeb.render('ExportTreeView-Secondary', {'fields': result}));
- }
- _.each(result, function(record) {
- if ((record.field_type == "one2many") && imp_cmpt) {
- var o2m_fld = self.$element.find("tr[id='treerow-" + record.id + "']").find('#tree-column');
- o2m_fld.addClass("oe_export_readonlyfield");
- }
- if ((record.required == true) || record.required == "True") {
- var required_fld = self.$element.find("tr[id='treerow-" + record.id + "']").find('#tree-column');
- required_fld.addClass("oe_export_requiredfield");
- }
- self.$element.find("img[id='parentimg-" + record.id +"']").click(function() {
- self.on_click(this.id, result);
- });
-
- self.$element.find("tr[id='treerow-" + record.id + "']").click(function(e) {
- if (e.shiftKey == true) {
- var frst_click, scnd_click = '';
- if (self.row_index == 0) {
- self.row_index = this.rowIndex;
- frst_click = self.$element.find("tr[id^='treerow-']")[self.row_index-1];
- $(frst_click).addClass("ui-selected");
- } else {
- if (this.rowIndex >=self.row_index) {
- for (i = (self.row_index-1); i < this.rowIndex; i++) {
- scnd_click = self.$element.find("tr[id^='treerow-']")[i];
- if (!$(scnd_click).find('#tree-column').hasClass("oe_export_readonlyfield")) {
- $(scnd_click).addClass("ui-selected");
- }
- }
- } else {
- for (i = (self.row_index-1); i >= (this.rowIndex-1); i--) {
- scnd_click = self.$element.find("tr[id^='treerow-']")[i];
- if (!$(scnd_click).find('#tree-column').hasClass("oe_export_readonlyfield")) {
- $(scnd_click).addClass("ui-selected");
- }
- }
- }
- }
- }
- self.row_index = this.rowIndex;
-
- self.$element.find("tr[id='treerow-" + record.id + "']").keyup(function(e) {
- self.row_index = 0;
- });
- var o2m_selection = self.$element.find("tr[id='treerow-" + record.id + "']").find('#tree-column');
- if ($(o2m_selection).hasClass("oe_export_readonlyfield")) {
- return false;
- }
- var selected = self.$element.find("tr.ui-selected");
- if ($(this).hasClass("ui-selected") && (e.ctrlKey == true)) {
- $(this).find('a').blur();
- $(this).removeClass("ui-selected");
- } else if ($(this).hasClass("ui-selected") && (e.ctrlKey == false) && (e.shiftKey == false)) {
- selected.find('a').blur();
- selected.removeClass("ui-selected");
- $(this).find('a').focus();
- $(this).addClass("ui-selected");
- } else if (!$(this).hasClass("ui-selected") && (e.ctrlKey == false) && (e.shiftKey == false)) {
- selected.find('a').blur();
- selected.removeClass("ui-selected");
- $(this).find('a').focus();
- $(this).addClass("ui-selected");
- } else if (!$(this).hasClass("ui-selected") && (e.ctrlKey == true)) {
- $(this).find('a').focus();
- $(this).addClass("ui-selected");
- }
- return false;
- });
-
- self.$element.find("tr[id='treerow-" + record.id + "']").keydown(function(e) {
- var keyCode = e.keyCode || e.which;
- arrow = {left: 37, up: 38, right: 39, down: 40 };
- switch (keyCode) {
- case arrow.left:
- if ($(this).find('img').attr('src') === '/base/static/src/img/collapse.gif') {
- self.on_click(this.id, result);
- }
- break;
- case arrow.up:
- var elem = this;
- $(elem).removeClass("ui-selected");
- while ($(elem).prev().is(":visible") == false) {
- elem = $(elem).prev();
- }
- if (!$(elem).prev().find('#tree-column').hasClass("oe_export_readonlyfield")) {
- $(elem).prev().addClass("ui-selected");
- }
- $(elem).prev().find('a').focus();
- break;
- case arrow.right:
- if ($(this).find('img').attr('src') == '/base/static/src/img/expand.gif') {
- self.on_click(this.id, result);
- }
- break;
- case arrow.down:
- var elem = this;
- $(elem).removeClass("ui-selected");
- while($(elem).next().is(":visible") == false) {
- elem = $(elem).next();
- }
- if (!$(elem).next().find('#tree-column').hasClass("oe_export_readonlyfield")) {
- $(elem).next().addClass("ui-selected");
- }
- $(elem).next().find('a').focus();
- break;
- }
- });
- self.$element.find("tr[id='treerow-" + record.id + "']").dblclick(function(e) {
- var $o2m_selection = self.$element.find("tr[id^='treerow-" + record.id + "']").find('#tree-column');
- if (!$o2m_selection.hasClass("oe_export_readonlyfield")) {
- var field_id = $(this).find("a").attr("id");
- if (field_id) {
- self.add_field(field_id.split('-')[1], $(this).find("a").attr("string"));
- }
- }
- });
- });
- self.$element.find('#fields_list').mouseover(function(event) {
- if (event.relatedTarget) {
- if (event.relatedTarget.attributes['id'] && event.relatedTarget.attributes['string']) {
- var field_id = event.relatedTarget.attributes["id"]["value"];
- if (field_id && field_id.split("-")[0] === 'export') {
- if (!self.$element.find("tr[id='treerow-" + field_id.split("-")[1] + "']").find('#tree-column').hasClass("oe_export_readonlyfield")) {
- self.add_field(field_id.split("-")[1], event.relatedTarget.attributes["string"]["value"]);
- }
- }
- }
- }
- });
- },
- showcontent: function(id, flag) {
- // show & hide the contents
- var first_child = this.$element.find("tr[id='treerow-" + id + "']").find('img');
- if (flag) {
- first_child.attr('src', '/base/static/src/img/expand.gif');
- }
- else {
- first_child.attr('src', '/base/static/src/img/collapse.gif');
- }
- var child_field = this.$element.find("tr[id^='treerow-" + id +"/']");
- var child_len = (id.split("/")).length + 1;
- for (var i = 0; i < child_field.length; i++) {
- if (flag) {
- $(child_field[i]).hide();
- } else {
- if (child_len == (child_field[i].id.split("/")).length) {
- if ($(child_field[i]).find('img').attr('src') == '/base/static/src/img/collapse.gif') {
- $(child_field[i]).find('img').attr('src', '/base/static/src/img/expand.gif');
- }
- $(child_field[i]).show();
- }
- }
- }
- },
- add_field: function(field_id, string) {
- var field_list = this.$element.find('#fields_list');
- if (this.$element.find("#fields_list option[value='" + field_id + "']") && !this.$element.find("#fields_list option[value='" + field_id + "']").length) {
- field_list.append(new Option(string, field_id));
- }
- },
- get_fields: function() {
- var export_field = [];
- this.$element.find("#fields_list option").each(function() {
- export_field.push($(this).val());
- });
- if (!export_field.length) {
- alert('Please select fields to save export list...');
- }
- return export_field;
- },
- on_click_export_data: function() {
- var self = this;
- var export_field = {};
- var flag = true;
- self.$element.find("#fields_list option").each(function() {
- export_field[$(this).val()] = $(this).text();
- flag = false;
- });
- if (flag) {
- alert('Please select fields to export...');
- return;
- }
-
- var import_comp = self.$element.find("#import_compat option:selected").val(),
- export_format = self.$element.find("#export_format").val();
-
- self.rpc("/base/export/export_data", {
- model: self.dataset.model,
- fields: export_field,
- ids: self.dataset.ids,
- domain: self.dataset.domain,
- import_compat: parseInt(import_comp),
- export_format: export_format
- }, function(data) {
- window.location = "data:text/csv/excel;charset=utf8," + data;
- self.close();
- });
- },
- close: function() {
- $(this.$dialog).remove();
- this._super();
- }
-});
-
-};
diff --git a/addons/base/static/src/js/dates.js b/addons/base/static/src/js/dates.js
deleted file mode 100644
index 71fdb759a63..00000000000
--- a/addons/base/static/src/js/dates.js
+++ /dev/null
@@ -1,138 +0,0 @@
-
-openerp.base.dates = function(openerp) {
-
-/**
- * Converts a string to a Date javascript object using OpenERP's
- * datetime string format (exemple: '2011-12-01 15:12:35').
- *
- * The timezone is assumed to be UTC (standard for OpenERP 6.1)
- * and will be converted to the browser's timezone.
- *
- * @param {String} str A string representing a datetime.
- * @returns {Date}
- */
-openerp.base.str_to_datetime = function(str) {
- if(!str) {
- return str;
- }
- var regex = /^(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d)(?:\.\d+)?$/;
- var res = regex.exec(str);
- if ( !res ) {
- throw "'" + str + "' is not a valid datetime";
- }
- var obj = Date.parse(res[1] + " GMT");
- if (! obj) {
- throw "'" + str + "' is not a valid datetime";
- }
- return obj;
-};
-
-/**
- * Converts a string to a Date javascript object using OpenERP's
- * date string format (exemple: '2011-12-01').
- *
- * @param {String} str A string representing a date.
- * @returns {Date}
- */
-openerp.base.str_to_date = function(str) {
- if(!str) {
- return str;
- }
- var regex = /^\d\d\d\d-\d\d-\d\d$/;
- var res = regex.exec(str);
- if ( !res ) {
- throw "'" + str + "' is not a valid date";
- }
- var obj = Date.parse(str);
- if (! obj) {
- throw "'" + str + "' is not a valid date";
- }
- return obj;
-};
-
-/**
- * Converts a string to a Date javascript object using OpenERP's
- * time string format (exemple: '15:12:35').
- *
- * @param {String} str A string representing a time.
- * @returns {Date}
- */
-openerp.base.str_to_time = function(str) {
- if(!str) {
- return str;
- }
- var regex = /^(\d\d:\d\d:\d\d)(?:\.\d+)?$/;
- var res = regex.exec(str);
- if ( !res ) {
- throw "'" + str + "' is not a valid time";
- }
- var obj = Date.parse(res[1]);
- if (! obj) {
- throw "'" + str + "' is not a valid time";
- }
- return obj;
-};
-
-/*
- * Left-pad provided arg 1 with zeroes until reaching size provided by second
- * argument.
- *
- * @param {Number|String} str value to pad
- * @param {Number} size size to reach on the final padded value
- * @returns {String} padded string
- */
-var zpad = function(str, size) {
- str = "" + str;
- return new Array(size - str.length + 1).join('0') + str;
-};
-
-/**
- * Converts a Date javascript object to a string using OpenERP's
- * datetime string format (exemple: '2011-12-01 15:12:35').
- *
- * The timezone of the Date object is assumed to be the one of the
- * browser and it will be converted to UTC (standard for OpenERP 6.1).
- *
- * @param {Date} obj
- * @returns {String} A string representing a datetime.
- */
-openerp.base.datetime_to_str = function(obj) {
- if (!obj) {
- return false;
- }
- return zpad(obj.getUTCFullYear(),4) + "-" + zpad(obj.getUTCMonth() + 1,2) + "-"
- + zpad(obj.getUTCDate(),2) + " " + zpad(obj.getUTCHours(),2) + ":"
- + zpad(obj.getUTCMinutes(),2) + ":" + zpad(obj.getUTCSeconds(),2);
-};
-
-/**
- * Converts a Date javascript object to a string using OpenERP's
- * date string format (exemple: '2011-12-01').
- *
- * @param {Date} obj
- * @returns {String} A string representing a date.
- */
-openerp.base.date_to_str = function(obj) {
- if (!obj) {
- return false;
- }
- return zpad(obj.getFullYear(),4) + "-" + zpad(obj.getMonth() + 1,2) + "-"
- + zpad(obj.getDate(),2);
-};
-
-/**
- * Converts a Date javascript object to a string using OpenERP's
- * time string format (exemple: '15:12:35').
- *
- * @param {Date} obj
- * @returns {String} A string representing a time.
- */
-openerp.base.time_to_str = function(obj) {
- if (!obj) {
- return false;
- }
- return zpad(obj.getHours(),2) + ":" + zpad(obj.getMinutes(),2) + ":"
- + zpad(obj.getSeconds(),2);
-};
-
-};
diff --git a/addons/base/static/src/js/form.js b/addons/base/static/src/js/form.js
deleted file mode 100644
index 2a3c8ab476e..00000000000
--- a/addons/base/static/src/js/form.js
+++ /dev/null
@@ -1,2477 +0,0 @@
-openerp.base.form = function (openerp) {
-
-var _t = openerp.base._t;
-
-openerp.base.views.add('form', 'openerp.base.FormView');
-openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormView# */{
- /**
- * Indicates that this view is not searchable, and thus that no search
- * view should be displayed (if there is one active).
- */
- searchable: false,
- template: "FormView",
- /**
- * @constructs
- * @param {openerp.base.Session} session the current openerp session
- * @param {String} element_id this view's root element id
- * @param {openerp.base.DataSet} dataset the dataset this view will work with
- * @param {String} view_id the identifier of the OpenERP view object
- *
- * @property {openerp.base.Registry} registry=openerp.base.form.widgets widgets registry for this form view instance
- */
- init: function(parent, element_id, dataset, view_id, options) {
- this._super(parent, element_id);
- this.set_default_options(options);
- this.dataset = dataset;
- this.model = dataset.model;
- this.view_id = view_id;
- this.fields_view = {};
- this.widgets = {};
- this.widgets_counter = 0;
- this.fields = {};
- this.datarecord = {};
- this.ready = false;
- this.show_invalid = true;
- this.dirty = false;
- this.default_focus_field = null;
- this.default_focus_button = null;
- this.registry = openerp.base.form.widgets;
- this.has_been_loaded = $.Deferred();
- this.$form_header = null;
- this.translatable_fields = [];
- _.defaults(this.options, {"always_show_new_button": true});
- },
- start: function() {
- //this.log('Starting FormView '+this.model+this.view_id)
- if (this.embedded_view) {
- var def = $.Deferred().then(this.on_loaded);
- var self = this;
- setTimeout(function() {def.resolve({fields_view: self.embedded_view});}, 0);
- return def.promise();
- } else {
- var context = new openerp.base.CompoundContext(this.dataset.get_context());
- return this.rpc("/base/formview/load", {"model": this.model, "view_id": this.view_id,
- toolbar: this.options.sidebar, context: context}, this.on_loaded);
- }
- },
- stop: function() {
- if (this.sidebar) {
- this.sidebar.attachments.stop();
- this.sidebar.stop();
- }
- _.each(this.widgets, function(w) {
- w.stop();
- });
- },
- on_loaded: function(data) {
- var self = this;
- this.fields_view = data.fields_view;
- var frame = new (this.registry.get_object('frame'))(this, this.fields_view.arch);
-
- this.$element.html(QWeb.render(this.template, { 'frame': frame, 'view': this }));
- _.each(this.widgets, function(w) {
- w.start();
- });
- this.$form_header = this.$element.find('#' + this.element_id + '_header');
- this.$form_header.find('div.oe_form_pager button[data-pager-action]').click(function() {
- var action = $(this).data('pager-action');
- self.on_pager_action(action);
- });
-
- this.$form_header.find('button.oe_form_button_save').click(this.do_save);
- this.$form_header.find('button.oe_form_button_save_edit').click(this.do_save_edit);
- this.$form_header.find('button.oe_form_button_cancel').click(this.do_cancel);
- this.$form_header.find('button.oe_form_button_new').click(this.on_button_new);
-
- if (this.session.debug) {
- this.$form_header.find('button.oe_get_xml_view').click(function() {
- $('<xmp>' + openerp.base.json_node_to_xml(self.fields_view.arch, true) + '</xmp>').dialog({ width: '95%', height: 600});
- });
- }
-
- if (this.options.sidebar && this.options.sidebar_id) {
- this.sidebar = new openerp.base.Sidebar(this, this.options.sidebar_id);
- this.sidebar.start();
- this.sidebar.do_unfold();
- this.sidebar.attachments = new openerp.base.form.SidebarAttachments(this.sidebar, this.sidebar.add_section('attachments', "Attachments"), this);
- this.sidebar.add_toolbar(data.fields_view.toolbar);
- this.set_common_sidebar_sections(this.sidebar);
- }
- this.has_been_loaded.resolve();
- },
- do_show: function () {
- var promise;
- if (this.dataset.index === null) {
- // null index means we should start a new record
- promise = this.on_button_new();
- } else {
- promise = this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded);
- }
- this.$element.show();
- if (this.sidebar) {
- this.sidebar.$element.show();
- }
- return promise;
- },
- do_hide: function () {
- this.$element.hide();
- if (this.sidebar) {
- this.sidebar.$element.hide();
- }
- },
- on_record_loaded: function(record) {
- if (!record) {
- throw("Form: No record received");
- }
- if (!record.id) {
- this.$form_header.find('.oe_form_on_create').show();
- this.$form_header.find('.oe_form_on_update').hide();
- if (!this.options["always_show_new_button"]) {
- this.$form_header.find('button.oe_form_button_new').hide();
- }
- } else {
- this.$form_header.find('.oe_form_on_create').hide();
- this.$form_header.find('.oe_form_on_update').show();
- this.$form_header.find('button.oe_form_button_new').show();
- }
- this.dirty = false;
- this.datarecord = record;
- for (var f in this.fields) {
- var field = this.fields[f];
- field.dirty = false;
- field.set_value(this.datarecord[f] || false);
- field.validate();
- }
- if (!record.id) {
- // New record: Second pass in order to trigger the onchanges
- this.dirty = true;
- this.show_invalid = false;
- for (var f in record) {
- var field = this.fields[f];
- if (field) {
- field.dirty = true;
- this.do_onchange(field);
- }
- }
- }
- this.on_form_changed();
- this.show_invalid = this.ready = true;
- this.do_update_pager(record.id == null);
- if (this.sidebar) {
- this.sidebar.attachments.do_update();
- this.sidebar.$element.find('.oe_sidebar_translate').toggleClass('oe_hide', !record.id);
- }
- if (this.default_focus_field && !this.embedded_view) {
- this.default_focus_field.focus();
- }
- },
- on_form_changed: function() {
- for (var w in this.widgets) {
- w = this.widgets[w];
- w.process_modifiers();
- w.update_dom();
- }
- },
- on_pager_action: function(action) {
- switch (action) {
- case 'first':
- this.dataset.index = 0;
- break;
- case 'previous':
- this.dataset.previous();
- break;
- case 'next':
- this.dataset.next();
- break;
- case 'last':
- this.dataset.index = this.dataset.ids.length - 1;
- break;
- }
- this.reload();
- },
- do_update_pager: function(hide_index) {
- var $pager = this.$element.find('#' + this.element_id + '_header div.oe_form_pager');
- var index = hide_index ? '-' : this.dataset.index + 1;
- $pager.find('span.oe_pager_index').html(index);
- $pager.find('span.oe_pager_count').html(this.dataset.ids.length);
- },
- do_onchange: function(widget, processed) {
- processed = processed || [];
- if (widget.node.attrs.on_change) {
- var self = this;
- this.ready = false;
- var onchange = _.trim(widget.node.attrs.on_change);
- var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/);
- if (call) {
- var method = call[1], args = [];
- var context_index = null;
- var argument_replacement = {
- 'False' : function() {return false;},
- 'True' : function() {return true;},
- 'None' : function() {return null;},
- 'context': function(i) {
- context_index = i;
- var ctx = widget.build_context ? widget.build_context() : {};
- return ctx;
- }
- }
- var parent_fields = null;
- _.each(call[2].split(','), function(a, i) {
- var field = _.trim(a);
- if (field in argument_replacement) {
- args.push(argument_replacement[field](i));
- return;
- } else if (self.fields[field]) {
- var value = self.fields[field].get_on_change_value();
- args.push(value == null ? false : value);
- return;
- } else {
- var splitted = field.split('.');
- if (splitted.length > 1 && _.trim(splitted[0]) === "parent" && self.dataset.parent_view) {
- if (parent_fields === null) {
- parent_fields = self.dataset.parent_view.get_fields_values();
- }
- var p_val = parent_fields[_.trim(splitted[1])];
- if (p_val !== undefined) {
- args.push(p_val == null ? false : p_val);
- return;
- }
- }
- }
- throw "Could not get field with name '" + field +
- "' for onchange '" + onchange + "'";
- });
- var ajax = {
- url: '/base/dataset/call',
- async: false
- };
- return this.rpc(ajax, {
- model: this.dataset.model,
- method: method,
- args: [(this.datarecord.id == null ? [] : [this.datarecord.id])].concat(args),
- context_id: context_index === null ? null : context_index + 1
- }, function(response) {
- self.on_processed_onchange(response, processed);
- });
- } else {
- this.log("Wrong on_change format", on_change);
- }
- }
- },
- on_processed_onchange: function(response, processed) {
- var result = response;
- if (result.value) {
- for (var f in result.value) {
- var field = this.fields[f];
- // If field is not defined in the view, just ignore it
- if (field) {
- var value = result.value[f];
- processed.push(field.name);
- if (field.get_value() != value) {
- field.set_value(value);
- field.dirty = true;
- if (_.indexOf(processed, field.name) < 0) {
- this.do_onchange(field, processed);
- }
- }
- }
- }
- this.on_form_changed();
- }
- if (!_.isEmpty(result.warning)) {
- $(QWeb.render("DialogWarning", result.warning)).dialog({
- modal: true,
- buttons: {
- Ok: function() {
- $(this).dialog("close");
- }
- }
- });
- }
- if (result.domain) {
- // TODO:
- }
- this.ready = true;
- },
- on_button_new: function() {
- var self = this;
- var def = $.Deferred();
- $.when(this.has_been_loaded).then(function() {
- self.dataset.default_get(
- _.keys(self.fields_view.fields)).then(self.on_record_loaded).then(function() {
- def.resolve();
- });
- });
- return def.promise();
- },
- /**
- * Triggers saving the form's record. Chooses between creating a new
- * record or saving an existing one depending on whether the record
- * already has an id property.
- *
- * @param {Function} success callback on save success
- * @param {Boolean} [prepend_on_create=false] if ``do_save`` creates a new record, should that record be inserted at the start of the dataset (by default, records are added at the end)
- */
- do_save: function(success, prepend_on_create) {
- var self = this;
- if (!this.ready) {
- return false;
- }
- var form_dirty = false,
- form_invalid = false,
- values = {},
- first_invalid_field = null;
- for (var f in this.fields) {
- f = this.fields[f];
- if (!f.is_valid()) {
- form_invalid = true;
- f.update_dom();
- if (!first_invalid_field) {
- first_invalid_field = f;
- }
- } else if (f.is_dirty()) {
- form_dirty = true;
- values[f.name] = f.get_value();
- }
- }
- if (form_invalid) {
- first_invalid_field.focus();
- this.on_invalid();
- return false;
- } else if (form_dirty) {
- this.log("About to save", values);
- if (!this.datarecord.id) {
- return this.dataset.create(values, function(r) {
- self.on_created(r, success, prepend_on_create);
- });
- } else {
- return this.dataset.write(this.datarecord.id, values, {}, function(r) {
- self.on_saved(r, success);
- });
- }
- } else {
- setTimeout(function() {
- self.on_saved({ result: true }, success);
- });
- return true;
- }
- },
- do_save_edit: function() {
- this.do_save();
- //this.switch_readonly(); Use promises
- },
- switch_readonly: function() {
- },
- switch_editable: function() {
- },
- on_invalid: function() {
- var msg = "<ul>";
- _.each(this.fields, function(f) {
- if (!f.is_valid()) {
- msg += "<li>" + f.string + "</li>";
- }
- });
- msg += "</ul>";
- this.notification.warn("The following fields are invalid :", msg);
- },
- on_saved: function(r, success) {
- if (!r.result) {
- this.notification.warn("Record not saved", "Problem while saving record.");
- } else {
- this.notification.notify("Record saved", "The record #" + this.datarecord.id + " has been saved.");
- if (success) {
- success(r);
- }
- this.reload();
- }
- },
- /**
- * Updates the form' dataset to contain the new record:
- *
- * * Adds the newly created record to the current dataset (at the end by
- * default)
- * * Selects that record (sets the dataset's index to point to the new
- * record's id).
- * * Updates the pager and sidebar displays
- *
- * @param {Object} r
- * @param {Function} success callback to execute after having updated the dataset
- * @param {Boolean} [prepend_on_create=false] adds the newly created record at the beginning of the dataset instead of the end
- */
- on_created: function(r, success, prepend_on_create) {
- if (!r.result) {
- this.notification.warn("Record not created", "Problem while creating record.");
- } else {
- this.datarecord.id = r.result;
- if (!prepend_on_create) {
- this.dataset.ids.push(this.datarecord.id);
- this.dataset.index = this.dataset.ids.length - 1;
- } else {
- this.dataset.ids.unshift(this.datarecord.id);
- this.dataset.index = 0;
- }
- this.do_update_pager();
- if (this.sidebar) {
- this.sidebar.attachments.do_update();
- }
- this.notification.notify("Record created", "The record has been created with id #" + this.datarecord.id);
- if (success) {
- success(_.extend(r, {created: true}));
- }
- this.reload();
- }
- },
- do_search: function (domains, contexts, groupbys) {
- this.notification.notify("Searching form");
- },
- on_action: function (action) {
- this.notification.notify('Executing action ' + action);
- },
- do_cancel: function () {
- this.notification.notify("Cancelling form");
- },
- reload: function() {
- if (this.dataset.index == null || this.dataset.index < 0) {
- this.on_button_new();
- } else {
- this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded);
- }
- },
- get_fields_values: function() {
- var values = {};
- _.each(this.fields, function(value, key) {
- var val = value.get_value();
- values[key] = val;
- });
- return values;
- },
- get_selected_ids: function() {
- var id = this.dataset.ids[this.dataset.index];
- return id ? [id] : [];
- }
-});
-
-/** @namespace */
-openerp.base.form = {};
-
-openerp.base.form.SidebarAttachments = openerp.base.Widget.extend({
- init: function(parent, element_id, form_view) {
- this._super(parent, element_id);
- this.view = form_view;
- },
- do_update: function() {
- if (!this.view.datarecord.id) {
- this.on_attachments_loaded([]);
- } else {
- (new openerp.base.DataSetSearch(
- this, 'ir.attachment', this.view.dataset.get_context(),
- [
- ['res_model', '=', this.view.dataset.model],
- ['res_id', '=', this.view.datarecord.id],
- ['type', 'in', ['binary', 'url']]
- ])).read_slice(['name', 'url', 'type'], {}, this.on_attachments_loaded);
- }
- },
- on_attachments_loaded: function(attachments) {
- this.attachments = attachments;
- this.$element.html(QWeb.render('FormView.sidebar.attachments', this));
- this.$element.find('.oe-binary-file').change(this.on_attachment_changed);
- this.$element.find('.oe-sidebar-attachment-delete').click(this.on_attachment_delete);
- },
- on_attachment_changed: function(e) {
- window[this.element_id + '_iframe'] = this.do_update;
- var $e = $(e.target);
- if ($e.val() != '') {
- this.$element.find('form.oe-binary-form').submit();
- $e.parent().find('input[type=file]').attr('disabled', 'true');
- $e.parent().find('button').attr('disabled', 'true').find('img, span').toggle();
- }
- },
- on_attachment_delete: function(e) {
- var self = this, $e = $(e.currentTarget);
- var name = _.trim($e.parent().find('a.oe-sidebar-attachments-link').text());
- if (confirm("Do you really want to delete the attachment " + name + " ?")) {
- this.rpc('/base/dataset/unlink', {
- model: 'ir.attachment',
- ids: [parseInt($e.attr('data-id'))]
- }, function(r) {
- $e.parent().remove();
- self.notification.notify("Delete an attachment", "The attachment '" + name + "' has been deleted");
- });
- }
- }
-});
-
-openerp.base.form.compute_domain = function(expr, fields) {
- var stack = [];
- for (var i = expr.length - 1; i >= 0; i--) {
- var ex = expr[i];
- if (ex.length == 1) {
- var top = stack.pop();
- switch (ex) {
- case '|':
- stack.push(stack.pop() || top);
- continue;
- case '&':
- stack.push(stack.pop() && top);
- continue;
- case '!':
- stack.push(!top);
- continue;
- default:
- throw new Error('Unknown domain operator ' + ex);
- }
- }
-
- var field = fields[ex[0]];
- if (!field) {
- throw new Error("Domain references unknown field : " + ex[0]);
- }
- var field_value = field.get_value ? fields[ex[0]].get_value() : fields[ex[0]].value;
- var op = ex[1];
- var val = ex[2];
-
- switch (op.toLowerCase()) {
- case '=':
- case '==':
- stack.push(field_value == val);
- break;
- case '!=':
- case '<>':
- stack.push(field_value != val);
- break;
- case '<':
- stack.push(field_value < val);
- break;
- case '>':
- stack.push(field_value > val);
- break;
- case '<=':
- stack.push(field_value <= val);
- break;
- case '>=':
- stack.push(field_value >= val);
- break;
- case 'in':
- stack.push(_(val).contains(field_value));
- break;
- case 'not in':
- stack.push(!_(val).contains(field_value));
- break;
- default:
- this.log("Unsupported operator in modifiers :", op);
- }
- }
- return _.all(stack, _.identity);
-};
-
-openerp.base.form.Widget = openerp.base.Widget.extend({
- template: 'Widget',
- init: function(view, node) {
- this.view = view;
- this.node = node;
- this.modifiers = JSON.parse(this.node.attrs.modifiers || '{}');
- this.type = this.type || node.tag;
- this.element_name = this.element_name || this.type;
- this.element_id = [this.view.element_id, this.element_name, this.view.widgets_counter++].join("_");
-
- this._super(view, this.element_id);
-
- this.view.widgets[this.element_id] = this;
- this.children = node.children;
- this.colspan = parseInt(node.attrs.colspan || 1, 10);
- this.decrease_max_width = 0;
-
- this.string = this.string || node.attrs.string;
- this.help = this.help || node.attrs.help;
- this.invisible = this.modifiers['invisible'] === true;
- this.classname = 'oe_form_' + this.type;
-
- this.width = this.node.attrs.width;
- },
- start: function() {
- this.$element = $('#' + this.element_id);
- },
- stop: function() {
- if (this.$element) {
- this.$element.remove();
- }
- },
- process_modifiers: function() {
- var compute_domain = openerp.base.form.compute_domain;
- for (var a in this.modifiers) {
- this[a] = compute_domain(this.modifiers[a], this.view.fields);
- }
- },
- update_dom: function() {
- this.$element.toggle(!this.invisible);
- },
- render: function() {
- var template = this.template;
- return QWeb.render(template, { "widget": this });
- }
-});
-
-openerp.base.form.WidgetFrame = openerp.base.form.Widget.extend({
- template: 'WidgetFrame',
- init: function(view, node) {
- this._super(view, node);
- this.columns = parseInt(node.attrs.col || 4, 10);
- this.x = 0;
- this.y = 0;
- this.table = [];
- this.add_row();
- for (var i = 0; i < node.children.length; i++) {
- var n = node.children[i];
- if (n.tag == "newline") {
- this.add_row();
- } else {
- this.handle_node(n);
- }
- }
- this.set_row_cells_with(this.table[this.table.length - 1]);
- },
- add_row: function(){
- if (this.table.length) {
- this.set_row_cells_with(this.table[this.table.length - 1]);
- }
- var row = [];
- this.table.push(row);
- this.x = 0;
- this.y += 1;
- return row;
- },
- set_row_cells_with: function(row) {
- var bypass = 0,
- max_width = 100;
- for (var i = 0; i < row.length; i++) {
- bypass += row[i].width === undefined ? 0 : 1;
- max_width -= row[i].decrease_max_width;
- }
- var size_unit = Math.round(max_width / (this.columns - bypass)),
- colspan_sum = 0;
- for (var i = 0; i < row.length; i++) {
- var w = row[i];
- colspan_sum += w.colspan;
- if (w.width === undefined) {
- var width = (i === row.length - 1 && colspan_sum === this.columns) ? max_width : Math.round(size_unit * w.colspan);
- max_width -= width;
- w.width = width + '%';
- }
- }
- },
- handle_node: function(node) {
- var type = {};
- if (node.tag == 'field') {
- type = this.view.fields_view.fields[node.attrs.name] || {};
- }
- var widget = new (this.view.registry.get_any(
- [node.attrs.widget, type.type, node.tag])) (this.view, node);
- if (node.tag == 'field') {
- if (!this.view.default_focus_field || node.attrs.default_focus == '1') {
- this.view.default_focus_field = widget;
- }
- if (node.attrs.nolabel != '1') {
- var label = new (this.view.registry.get_object('label')) (this.view, node);
- label["for"] = widget;
- this.add_widget(label, widget.colspan + 1);
- }
- }
- this.add_widget(widget);
- },
- add_widget: function(widget, colspan) {
- colspan = colspan || widget.colspan;
- var current_row = this.table[this.table.length - 1];
- if (current_row.length && (this.x + colspan) > this.columns) {
- current_row = this.add_row();
- }
- current_row.push(widget);
- this.x += widget.colspan;
- return widget;
- }
-});
-
-openerp.base.form.WidgetNotebook = openerp.base.form.Widget.extend({
- template: 'WidgetNotebook',
- init: function(view, node) {
- this._super(view, node);
- this.pages = [];
- for (var i = 0; i < node.children.length; i++) {
- var n = node.children[i];
- if (n.tag == "page") {
- var page = new openerp.base.form.WidgetNotebookPage(this.view, n, this, this.pages.length);
- this.pages.push(page);
- }
- }
- },
- start: function() {
- this._super.apply(this, arguments);
- this.$element.tabs();
- this.view.on_button_new.add_last(this.do_select_first_visible_tab);
- },
- do_select_first_visible_tab: function() {
- for (var i = 0; i < this.pages.length; i++) {
- var page = this.pages[i];
- if (page.invisible === false) {
- this.$element.tabs('select', page.index);
- break;
- }
- }
- }
-});
-
-openerp.base.form.WidgetNotebookPage = openerp.base.form.WidgetFrame.extend({
- template: 'WidgetNotebookPage',
- init: function(view, node, notebook, index) {
- this.notebook = notebook;
- this.index = index;
- this.element_name = 'page_' + index;
- this._super(view, node);
- this.element_tab_id = this.element_id + '_tab';
- },
- start: function() {
- this._super.apply(this, arguments);
- this.$element_tab = $('#' + this.element_tab_id);
- },
- update_dom: function() {
- if (this.invisible && this.index === this.notebook.$element.tabs('option', 'selected')) {
- this.notebook.do_select_first_visible_tab();
- }
- this.$element_tab.toggle(!this.invisible);
- this.$element.toggle(!this.invisible);
- }
-});
-
-openerp.base.form.WidgetSeparator = openerp.base.form.Widget.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "WidgetSeparator";
- this.orientation = node.attrs.orientation || 'horizontal';
- if (this.orientation === 'vertical') {
- this.width = '1';
- }
- this.classname += '_' + this.orientation;
- }
-});
-
-openerp.base.form.WidgetButton = openerp.base.form.Widget.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "WidgetButton";
- if (this.string) {
- // We don't have button key bindings in the webclient
- this.string = this.string.replace(/_/g, '');
- }
- if (node.attrs.default_focus == '1') {
- // TODO fme: provide enter key binding to widgets
- this.view.default_focus_button = this;
- }
- },
- start: function() {
- this._super.apply(this, arguments);
- this.$element.click(this.on_click);
- },
- on_click: function(saved) {
- var self = this;
- if (!this.node.attrs.special && this.view.dirty && saved !== true) {
- this.view.do_save(function() {
- self.on_click(true);
- });
- } else {
- if (this.node.attrs.confirm) {
- var dialog = $('<div>' + this.node.attrs.confirm + '</div>').dialog({
- title: 'Confirm',
- modal: true,
- buttons: {
- Ok: function() {
- self.on_confirmed();
- $(this).dialog("close");
- },
- Cancel: function() {
- $(this).dialog("close");
- }
- }
- });
- } else {
- this.on_confirmed();
- }
- }
- },
- on_confirmed: function() {
- var self = this;
-
- this.view.execute_action(
- this.node.attrs, this.view.dataset, this.view.datarecord.id, function () {
- self.view.reload();
- });
- }
-});
-
-openerp.base.form.WidgetLabel = openerp.base.form.Widget.extend({
- init: function(view, node) {
- this.element_name = 'label_' + node.attrs.name;
-
- this._super(view, node);
-
- // TODO fme: support for attrs.align
- if (this.node.tag == 'label' && (this.node.attrs.colspan || (this.string && this.string.length > 32))) {
- this.template = "WidgetParagraph";
- this.colspan = parseInt(this.node.attrs.colspan || 1, 10);
- } else {
- this.template = "WidgetLabel";
- this.colspan = 1;
- this.width = '1%';
- this.decrease_max_width = 1;
- this.nowrap = true;
- }
- },
- render: function () {
- if (this['for'] && this.type !== 'label') {
- return QWeb.render(this.template, {widget: this['for']});
- }
- // Actual label widgets should not have a false and have type label
- return QWeb.render(this.template, {widget: this});
- },
- start: function() {
- this._super();
- var self = this;
- this.$element.find("label").dblclick(function() {
- var widget = self['for'] || self;
- self.log(widget.element_id , widget);
- window.w = widget;
- });
- }
-});
-
-openerp.base.form.Field = openerp.base.form.Widget.extend({
- init: function(view, node) {
- this.name = node.attrs.name;
- this.value = undefined;
- view.fields[this.name] = this;
- this.type = node.attrs.widget || view.fields_view.fields[node.attrs.name].type;
- this.element_name = "field_" + this.name + "_" + this.type;
-
- this._super(view, node);
-
- if (node.attrs.nolabel != '1' && this.colspan > 1) {
- this.colspan--;
- }
- this.field = view.fields_view.fields[node.attrs.name] || {};
- this.string = node.attrs.string || this.field.string;
- this.help = node.attrs.help || this.field.help;
- this.nolabel = (this.field.nolabel || node.attrs.nolabel) === '1';
- this.readonly = this.modifiers['readonly'] === true;
- this.required = this.modifiers['required'] === true;
- this.invalid = false;
- this.dirty = false;
-
- this.classname = 'oe_form_field_' + this.type;
- },
- start: function() {
- this._super.apply(this, arguments);
- if (this.field.translate) {
- this.view.translatable_fields.push(this);
- this.$element.find('.oe_field_translate').click(this.on_translate);
- }
- },
- set_value: function(value) {
- this.value = value;
- this.invalid = false;
- this.update_dom();
- this.on_value_changed();
- },
- set_value_from_ui: function() {
- this.on_value_changed();
- },
- on_value_changed: function() {
- },
- on_translate: function() {
- this.view.open_translate_dialog(this);
- },
- get_value: function() {
- return this.value;
- },
- is_valid: function() {
- return !this.invalid;
- },
- is_dirty: function() {
- return this.dirty;
- },
- get_on_change_value: function() {
- return this.get_value();
- },
- update_dom: function() {
- this._super.apply(this, arguments);
- if (this.field.translate) {
- this.$element.find('.oe_field_translate').toggle(!!this.view.datarecord.id);
- }
- if (!this.disable_utility_classes) {
- this.$element.toggleClass('disabled', this.readonly);
- this.$element.toggleClass('required', this.required);
- if (this.view.show_invalid) {
- this.$element.toggleClass('invalid', !this.is_valid());
- }
- }
- },
- on_ui_change: function() {
- this.dirty = this.view.dirty = true;
- this.validate();
- if (this.is_valid()) {
- this.set_value_from_ui();
- this.view.do_onchange(this);
- this.view.on_form_changed();
- } else {
- this.update_dom();
- }
- },
- validate: function() {
- this.invalid = false;
- },
- focus: function() {
- },
- _build_view_fields_values: function() {
- var a_dataset = this.view.dataset || {};
- var fields_values = this.view.get_fields_values();
- var parent_values = a_dataset.parent_view ? a_dataset.parent_view.get_fields_values() : {};
- fields_values.parent = parent_values;
- return fields_values;
- },
- /**
- * Builds a new context usable for operations related to fields by merging
- * the fields'context with the action's context.
- */
- build_context: function() {
- // I previously belevied contexts should be herrited, but now I doubt it
- //var a_context = this.view.dataset.get_context() || {};
- var f_context = this.field.context || null;
- // maybe the default_get should only be used when we do a default_get?
- var v_context1 = this.node.attrs.default_get || {};
- var v_context2 = this.node.attrs.context || {};
- var v_context = new openerp.base.CompoundContext(v_context1, v_context2);
- if (v_context1.__ref || v_context2.__ref || true) { //TODO niv: remove || true
- var fields_values = this._build_view_fields_values();
- v_context.set_eval_context(fields_values);
- }
- // if there is a context on the node, overrides the model's context
- var ctx = f_context || v_context;
- return ctx;
- },
- build_domain: function() {
- var f_domain = this.field.domain || null;
- var v_domain = this.node.attrs.domain || [];
- if (!(v_domain instanceof Array) || true) { //TODO niv: remove || true
- var fields_values = this._build_view_fields_values();
- v_domain = new openerp.base.CompoundDomain(v_domain).set_eval_context(fields_values);
- }
- // if there is a domain on the node, overrides the model's domain
- return f_domain || v_domain;
- }
-});
-
-openerp.base.form.FieldChar = openerp.base.form.Field.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldChar";
- },
- start: function() {
- this._super.apply(this, arguments);
- this.$element.find('input').change(this.on_ui_change);
- },
- set_value: function(value) {
- this._super.apply(this, arguments);
- var show_value = openerp.base.format_value(value, this, '');
- this.$element.find('input').val(show_value);
- },
- update_dom: function() {
- this._super.apply(this, arguments);
- this.$element.find('input').attr('disabled', this.readonly);
- },
- set_value_from_ui: function() {
- this.value = openerp.base.parse_value(this.$element.find('input').val(), this);
- this._super();
- },
- validate: function() {
- this.invalid = false;
- try {
- var value = openerp.base.parse_value(this.$element.find('input').val(), this, '');
- this.invalid = this.required && value === '';
- } catch(e) {
- this.invalid = true;
- }
- },
- focus: function() {
- this.$element.find('input').focus();
- }
-});
-
-openerp.base.form.FieldEmail = openerp.base.form.FieldChar.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldEmail";
- },
- start: function() {
- this._super.apply(this, arguments);
- this.$element.find('button').click(this.on_button_clicked);
- },
- on_button_clicked: function() {
- if (!this.value || !this.is_valid()) {
- this.notification.warn("E-mail error", "Can't send email to invalid e-mail address");
- } else {
- location.href = 'mailto:' + this.value;
- }
- },
- set_value: function(value) {
- this._super.apply(this, arguments);
- this.$element.find('a').attr('href', 'mailto:' + this.$element.find('input').val());
- }
-});
-
-openerp.base.form.FieldUrl = openerp.base.form.FieldChar.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldUrl";
- },
- start: function() {
- this._super.apply(this, arguments);
- this.$element.find('button').click(this.on_button_clicked);
- },
- on_button_clicked: function() {
- if (!this.value) {
- this.notification.warn("Resource error", "This resource is empty");
- } else {
- window.open(this.value);
- }
- }
-});
-
-openerp.base.form.FieldFloat = openerp.base.form.FieldChar.extend({
- set_value: function(value) {
- if (value === false || value === undefined) {
- // As in GTK client, floats default to 0
- value = 0;
- this.dirty = true;
- }
- this._super.apply(this, [value]);
- }
-});
-
-openerp.base.form.FieldDatetime = openerp.base.form.Field.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldDate";
- this.jqueryui_object = 'datetimepicker';
- },
- start: function() {
- this._super.apply(this, arguments);
- this.$element.find('input').change(this.on_ui_change)[this.jqueryui_object]({
- dateFormat: 'yy-mm-dd',
- timeFormat: 'hh:mm:ss',
- showOn: 'button',
- buttonImage: '/base/static/src/img/ui/field_calendar.png',
- buttonImageOnly: true,
- constrainInput: false
- });
- },
- set_value: function(value) {
- this._super.apply(this, arguments);
- if (!value) {
- this.$element.find('input').val('');
- } else {
- this.$element.find('input').unbind('change');
- // jQuery UI date picker wrongly call on_change event herebelow
- this.$element.find('input')[this.jqueryui_object]('setDate', this.parse(value));
- this.$element.find('input').change(this.on_ui_change);
- }
- },
- set_value_from_ui: function() {
- this.value = this.$element.find('input')[this.jqueryui_object]('getDate') || false;
- if (this.value) {
- this.value = this.format(this.value);
- }
- this._super();
- },
- update_dom: function() {
- this._super.apply(this, arguments);
- this.$element.find('input').datepicker(this.readonly ? 'disable' : 'enable');
- },
- validate: function() {
- this.invalid = false;
- var value = this.$element.find('input').val();
- if (value === "") {
- this.invalid = this.required;
- } else {
- this.invalid = !this.$element.find('input')[this.jqueryui_object]('getDate');
- }
- },
- focus: function() {
- this.$element.find('input').focus();
- },
- parse: openerp.base.auto_str_to_date,
- format: function(val) {
- return openerp.base.auto_date_to_str(val, this.field.type);
- }
-});
-
-openerp.base.form.FieldDate = openerp.base.form.FieldDatetime.extend({
- init: function(view, node) {
- this._super(view, node);
- this.jqueryui_object = 'datepicker';
- }
-});
-
-openerp.base.form.FieldText = openerp.base.form.Field.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldText";
- },
- start: function() {
- this._super.apply(this, arguments);
- this.$element.find('textarea').change(this.on_ui_change);
- },
- set_value: function(value) {
- this._super.apply(this, arguments);
- var show_value = openerp.base.format_value(value, this, '');
- this.$element.find('textarea').val(show_value);
- },
- update_dom: function() {
- this._super.apply(this, arguments);
- this.$element.find('textarea').attr('disabled', this.readonly);
- },
- set_value_from_ui: function() {
- this.value = openerp.base.parse_value(this.$element.find('textarea').val(), this);
- this._super();
- },
- validate: function() {
- this.invalid = false;
- try {
- var value = openerp.base.parse_value(this.$element.find('textarea').val(), this, '');
- this.invalid = this.required && value === '';
- } catch(e) {
- this.invalid = true;
- }
- },
- focus: function() {
- this.$element.find('textarea').focus();
- }
-});
-
-openerp.base.form.FieldBoolean = openerp.base.form.Field.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldBoolean";
- },
- start: function() {
- var self = this;
- this._super.apply(this, arguments);
- this.$element.find('input').click(function() {
- if ($(this).is(':checked') != self.value) {
- self.on_ui_change();
- }
- });
- },
- set_value: function(value) {
- this._super.apply(this, arguments);
- this.$element.find('input')[0].checked = value;
- },
- set_value_from_ui: function() {
- this.value = this.$element.find('input').is(':checked');
- this._super();
- },
- update_dom: function() {
- this._super.apply(this, arguments);
- this.$element.find('input').attr('disabled', this.readonly);
- },
- validate: function() {
- this.invalid = this.required && !this.$element.find('input').is(':checked');
- },
- focus: function() {
- this.$element.find('input').focus();
- }
-});
-
-openerp.base.form.FieldProgressBar = openerp.base.form.Field.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldProgressBar";
- },
- start: function() {
- this._super.apply(this, arguments);
- this.$element.find('div').progressbar({
- value: this.value,
- disabled: this.readonly
- });
- },
- set_value: function(value) {
- this._super.apply(this, arguments);
- var show_value = Number(value);
- if (isNaN(show_value)) {
- show_value = 0;
- }
- this.$element.find('div').progressbar('option', 'value', show_value).find('span').html(show_value + '%');
- }
-});
-
-openerp.base.form.FieldTextXml = openerp.base.form.Field.extend({
-// to replace view editor
-});
-
-openerp.base.form.FieldSelection = openerp.base.form.Field.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldSelection";
- this.field_index = _.map(this.field.selection, function(x, index) {
- return {"ikey": "" + index, "ekey": x[0], "label": x[1]};
- });
- },
- start: function() {
- // Flag indicating whether we're in an event chain containing a change
- // event on the select, in order to know what to do on keyup[RETURN]:
- // * If the user presses [RETURN] as part of changing the value of a
- // selection, we should just let the value change and not let the
- // event broadcast further (e.g. to validating the current state of
- // the form in editable list view, which would lead to saving the
- // current row or switching to the next one)
- // * If the user presses [RETURN] with a select closed (side-effect:
- // also if the user opened the select and pressed [RETURN] without
- // changing the selected value), takes the action as validating the
- // row
- var ischanging = false;
- this._super.apply(this, arguments);
- this.$element.find('select')
- .change(this.on_ui_change)
- .change(function () { ischanging = true; })
- .click(function () { ischanging = false; })
- .keyup(function (e) {
- if (e.which !== 13 || !ischanging) { return; }
- e.stopPropagation();
- ischanging = false;
- });
- },
- set_value: function(value) {
- value = value === null ? false : value;
- value = value instanceof Array ? value[0] : value;
- this._super(value);
- var option = _.detect(this.field_index, function(x) {return x.ekey === value;});
- this.$element.find('select').val(option === undefined ? '' : option.ikey);
- },
- set_value_from_ui: function() {
- var ikey = this.$element.find('select').val();
- var option = _.detect(this.field_index, function(x) {return x.ikey === ikey;});
- this.value = option === undefined ? false : option.ekey;
- this._super();
- },
- update_dom: function() {
- this._super.apply(this, arguments);
- this.$element.find('select').attr('disabled', this.readonly);
- },
- validate: function() {
- var ikey = this.$element.find('select').val();
- var option = _.detect(this.field_index, function(x) {return x.ikey === ikey;});
- this.invalid = this.required && (option === undefined || option.ekey === false);
- },
- focus: function() {
- this.$element.find('select').focus();
- }
-});
-
-// jquery autocomplete tweak to allow html
-(function() {
- var proto = $.ui.autocomplete.prototype,
- initSource = proto._initSource;
-
- function filter( array, term ) {
- var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
- return $.grep( array, function(value) {
- return matcher.test( $( "<div>" ).html( value.label || value.value || value ).text() );
- });
- }
-
- $.extend( proto, {
- _initSource: function() {
- if ( this.options.html && $.isArray(this.options.source) ) {
- this.source = function( request, response ) {
- response( filter( this.options.source, request.term ) );
- };
- } else {
- initSource.call( this );
- }
- },
-
- _renderItem: function( ul, item) {
- return $( "<li></li>" )
- .data( "item.autocomplete", item )
- .append( $( "<a></a>" )[ this.options.html ? "html" : "text" ]( item.label ) )
- .appendTo( ul );
- }
- });
-})();
-
-openerp.base.form.dialog = function(content, options) {
- options = _.extend({
- autoOpen: true,
- width: '90%',
- height: '90%',
- min_width: '800px',
- min_height: '600px'
- }, options || {});
- options.autoOpen = true;
- var dialog = new openerp.base.Dialog(null, options);
- dialog.$dialog = $(content).dialog(dialog.dialog_options);
- return dialog.$dialog;
-}
-
-openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldMany2One";
- this.limit = 7;
- this.value = null;
- this.cm_id = _.uniqueId('m2o_cm_');
- this.last_search = [];
- this.tmp_value = undefined;
- },
- start: function() {
- this._super();
- var self = this;
- this.$input = this.$element.find("input");
- this.$drop_down = this.$element.find(".oe-m2o-drop-down-button");
- this.$menu_btn = this.$element.find(".oe-m2o-cm-button");
-
- // context menu
- var init_context_menu_def = $.Deferred().then(function(e) {
- var rdataset = new openerp.base.DataSetStatic(self, "ir.values", self.build_context());
- rdataset.call("get", ['action', 'client_action_relate',
- [[self.field.relation, false]], false, rdataset.get_context()], false, 0)
- .then(function(result) {
- self.related_entries = result;
-
- var $cmenu = $("#" + self.cm_id);
- $cmenu.append(QWeb.render("FieldMany2One.context_menu", {widget: self}));
- var bindings = {};
- bindings[self.cm_id + "_search"] = function() {
- self._search_create_popup("search");
- };
- bindings[self.cm_id + "_create"] = function() {
- self._search_create_popup("form");
- };
- bindings[self.cm_id + "_open"] = function() {
- if (!self.value) {
- return;
- }
- var pop = new openerp.base.form.FormOpenPopup(self.view);
- pop.show_element(self.field.relation, self.value[0],self.build_context(), {});
- pop.on_write_completed.add_last(function() {
- self.set_value(self.value[0]);
- });
- };
- _.each(_.range(self.related_entries.length), function(i) {
- bindings[self.cm_id + "_related_" + i] = function() {
- self.open_related(self.related_entries[i]);
- };
- });
- var cmenu = self.$menu_btn.contextMenu(self.cm_id, {'leftClickToo': true,
- bindings: bindings, itemStyle: {"color": ""},
- onContextMenu: function() {
- if(self.value) {
- $("#" + self.cm_id + " .oe_m2o_menu_item_mandatory").removeClass("oe-m2o-disabled-cm");
- } else {
- $("#" + self.cm_id + " .oe_m2o_menu_item_mandatory").addClass("oe-m2o-disabled-cm");
- }
- return true;
- }, menuStyle: {width: "200px"}
- });
- setTimeout(function() {self.$menu_btn.trigger(e);}, 0);
- });
- });
- var ctx_callback = function(e) {init_context_menu_def.resolve(e); e.preventDefault()};
- this.$menu_btn.bind('contextmenu', ctx_callback);
- this.$menu_btn.click(ctx_callback);
-
- // some behavior for input
- this.$input.keyup(function() {
- if (self.$input.val() === "") {
- self._change_int_value(null);
- } else if (self.value === null || (self.value && self.$input.val() !== self.value[1])) {
- self._change_int_value(undefined);
- }
- });
- this.$drop_down.click(function() {
- if (self.$input.autocomplete("widget").is(":visible")) {
- self.$input.autocomplete("close");
- } else {
- if (self.value) {
- self.$input.autocomplete("search", "");
- } else {
- self.$input.autocomplete("search");
- }
- self.$input.focus();
- }
- });
- var anyoneLoosesFocus = function() {
- if (!self.$input.is(":focus") &&
- !self.$input.autocomplete("widget").is(":visible") &&
- !self.value) {
- if(self.value === undefined && self.last_search.length > 0) {
- self._change_int_ext_value(self.last_search[0]);
- } else {
- self._change_int_ext_value(null);
- }
- }
- }
- this.$input.focusout(anyoneLoosesFocus);
-
- var isSelecting = false;
- // autocomplete
- this.$input.autocomplete({
- source: function(req, resp) { self.get_search_result(req, resp); },
- select: function(event, ui) {
- isSelecting = true;
- var item = ui.item;
- if (item.id) {
- self._change_int_value([item.id, item.name]);
- } else if (item.action) {
- self._change_int_value(undefined);
- item.action();
- return false;
- }
- },
- focus: function(e, ui) {
- e.preventDefault();
- },
- html: true,
- close: anyoneLoosesFocus,
- minLength: 0,
- delay: 0
- });
- // used to correct a bug when selecting an element by pushing 'enter' in an editable list
- this.$input.keyup(function(e) {
- if (e.which === 13) {
- if (isSelecting)
- e.stopPropagation();
- }
- isSelecting = false;
- });
- },
- // autocomplete component content handling
- get_search_result: function(request, response) {
- var search_val = request.term;
- var self = this;
-
- var dataset = new openerp.base.DataSetStatic(this, this.field.relation, self.build_context());
-
- dataset.name_search(search_val, self.build_domain(), 'ilike',
- this.limit + 1, function(data) {
- self.last_search = data;
- // possible selections for the m2o
- var values = _.map(data, function(x) {
- return {label: $('<span />').text(x[1]).html(), name:x[1], id:x[0]};
- });
-
- // search more... if more results that max
- if (values.length > self.limit) {
- values = values.slice(0, self.limit);
- values.push({label: _t("<em>   Search More...</em>"), action: function() {
- dataset.name_search(search_val, self.build_domain(), 'ilike'
- , false, function(data) {
- self._change_int_value(null);
- self._search_create_popup("search", data);
- });
- }});
- }
- // quick create
- var raw_result = _(data.result).map(function(x) {return x[1];})
- if (search_val.length > 0 &&
- !_.include(raw_result, search_val) &&
- (!self.value || search_val !== self.value[1])) {
- values.push({label: _.sprintf(_t('<em>   Create "<strong>%s</strong>"</em>'),
- $('<span />').text(search_val).html()), action: function() {
- self._quick_create(search_val);
- }});
- }
- // create...
- values.push({label: _t("<em>   Create and Edit...</em>"), action: function() {
- self._change_int_value(null);
- self._search_create_popup("form", undefined, {"default_name": search_val});
- }});
-
- response(values);
- });
- },
- _quick_create: function(name) {
- var self = this;
- var dataset = new openerp.base.DataSetStatic(this, this.field.relation, self.build_context());
- dataset.name_create(name, function(data) {
- self._change_int_ext_value(data);
- }).fail(function(error, event) {
- event.preventDefault();
- self._change_int_value(null);
- self._search_create_popup("form", undefined, {"default_name": name});
- });
- },
- // all search/create popup handling
- _search_create_popup: function(view, ids, context) {
- var self = this;
- var pop = new openerp.base.form.SelectCreatePopup(this);
- pop.select_element(self.field.relation,{
- initial_ids: ids ? _.map(ids, function(x) {return x[0]}) : undefined,
- initial_view: view,
- disable_multiple_selection: true
- }, self.build_domain(),
- new openerp.base.CompoundContext(self.build_context(), context || {}));
- pop.on_select_elements.add(function(element_ids) {
- var dataset = new openerp.base.DataSetStatic(self, self.field.relation, self.build_context());
- dataset.name_get([element_ids[0]], function(data) {
- self._change_int_ext_value(data[0]);
- });
- });
- },
- _change_int_ext_value: function(value) {
- this._change_int_value(value);
- this.$input.val(this.value ? this.value[1] : "");
- },
- _change_int_value: function(value) {
- this.value = value;
- var back_orig_value = this.original_value;
- if (this.value === null || this.value) {
- this.original_value = this.value;
- }
- if (back_orig_value === undefined) { // first use after a set_value()
- return;
- }
- if (this.value !== undefined && ((back_orig_value ? back_orig_value[0] : null)
- !== (this.value ? this.value[0] : null))) {
- this.on_ui_change();
- }
- },
- set_value: function(value) {
- value = value || null;
- this.invalid = false;
- var self = this;
- this.tmp_value = value;
- self.update_dom();
- self.on_value_changed();
- var real_set_value = function(rval) {
- self.tmp_value = undefined;
- self.value = rval;
- self.original_value = undefined;
- self._change_int_ext_value(rval);
- };
- if(typeof(value) === "number") {
- var dataset = new openerp.base.DataSetStatic(this, this.field.relation, self.build_context());
- dataset.name_get([value], function(data) {
- real_set_value(data[0]);
- }).fail(function() {self.tmp_value = undefined;});
- } else {
- setTimeout(function() {real_set_value(value);}, 0);
- }
- },
- get_value: function() {
- if (this.tmp_value !== undefined) {
- if (this.tmp_value instanceof Array) {
- return this.tmp_value[0];
- }
- return this.tmp_value ? this.tmp_value : false;
- }
- if (this.value === undefined)
- return this.original_value ? this.original_value[0] : false;
- return this.value ? this.value[0] : false;
- },
- validate: function() {
- this.invalid = false;
- var val = this.tmp_value !== undefined ? this.tmp_value : this.value;
- if (val === null) {
- this.invalid = this.required;
- }
- },
- open_related: function(related) {
- var self = this;
- if (!self.value)
- return;
- var additional_context = {
- active_id: self.value[0],
- active_ids: [self.value[0]],
- active_model: self.field.relation
- };
- self.rpc("/base/action/load", {
- action_id: related[2].id,
- context: additional_context
- }, function(result) {
- result.result.context = _.extend(result.result.context || {}, additional_context);
- self.do_action(result.result);
- });
- }
-});
-
-/*
-# Values: (0, 0, { fields }) create
-# (1, ID, { fields }) update
-# (2, ID) remove (delete)
-# (3, ID) unlink one (target id or target of relation)
-# (4, ID) link
-# (5) unlink all (only valid for one2many)
-*/
-var commands = {
- // (0, _, {values})
- CREATE: 0,
- 'create': function (values) {
- return [commands.CREATE, false, values];
- },
- // (1, id, {values})
- UPDATE: 1,
- 'update': function (id, values) {
- return [commands.UPDATE, id, values];
- },
- // (2, id[, _])
- DELETE: 2,
- 'delete': function (id) {
- return [commands.DELETE, id, false];
- },
- // (3, id[, _]) removes relation, but not linked record itself
- FORGET: 3,
- 'forget': function (id) {
- return [commands.FORGET, id, false];
- },
- // (4, id[, _])
- LINK_TO: 4,
- 'link_to': function (id) {
- return [commands.LINK_TO, id, false];
- },
- // (5[, _[, _]])
- DELETE_ALL: 5,
- 'delete_all': function () {
- return [5, false, false];
- },
- // (6, _, ids) replaces all linked records with provided ids
- REPLACE_WITH: 6,
- 'replace_with': function (ids) {
- return [6, false, ids];
- }
-};
-openerp.base.form.FieldOne2Many = openerp.base.form.Field.extend({
- multi_selection: false,
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldOne2Many";
- this.is_started = $.Deferred();
- this.form_last_update = $.Deferred();
- this.disable_utility_classes = true;
- },
- start: function() {
- this._super.apply(this, arguments);
-
- var self = this;
-
- this.dataset = new openerp.base.form.One2ManyDataSet(this, this.field.relation);
- this.dataset.o2m = this;
- this.dataset.parent_view = this.view;
- this.dataset.on_change.add_last(function() {
- self.on_ui_change();
- });
-
- var modes = this.node.attrs.mode;
- modes = !!modes ? modes.split(",") : ["tree", "form"];
- var views = [];
- _.each(modes, function(mode) {
- var view = {
- view_id: false,
- view_type: mode == "tree" ? "list" : mode,
- options: { sidebar : false }
- };
- if (self.field.views && self.field.views[mode]) {
- view.embedded_view = self.field.views[mode];
- }
- if(view.view_type === "list") {
- view.options.selectable = self.multi_selection;
- }
- views.push(view);
- });
- this.views = views;
-
- this.viewmanager = new openerp.base.ViewManager(this, this.dataset, views);
- this.viewmanager.registry = openerp.base.views.clone({
- list: 'openerp.base.form.One2ManyListView',
- form: 'openerp.base.form.One2ManyFormView'
- });
- var once = $.Deferred().then(function() {
- self.form_last_update.resolve();
- });
- this.viewmanager.on_controller_inited.add_last(function(view_type, controller) {
- if (view_type == "list") {
- controller.o2m = self;
- } else if (view_type == "form") {
- controller.on_record_loaded.add_last(function() {
- once.resolve();
- });
- controller.on_pager_action.add_first(function() {
- self.save_form_view();
- });
- controller.$element.find(".oe_form_button_save_edit").hide();
- }
- self.is_started.resolve();
- });
- this.viewmanager.on_mode_switch.add_first(function() {
- self.save_form_view();
- });
- setTimeout(function () {
- self.viewmanager.appendTo(self.$element);
- }, 0);
- },
- reload_current_view: function() {
- var self = this;
- var view = self.viewmanager.views[self.viewmanager.active_view].controller;
- if(self.viewmanager.active_view === "list") {
- view.reload_content();
- } else if (self.viewmanager.active_view === "form") {
- if (this.dataset.index === null && this.dataset.ids.length >= 1) {
- this.dataset.index = 0;
- }
- this.form_last_update.then(function() {
- this.form_last_update = view.do_show();
- });
- }
- },
- set_value: function(value) {
- value = value || [];
- var self = this;
- this.dataset.reset_ids([]);
- if(value.length >= 1 && value[0] instanceof Array) {
- var ids = [];
- _.each(value, function(command) {
- var obj = {values: command[2]};
- switch (command[0]) {
- case commands.CREATE:
- obj['id'] = _.uniqueId(self.dataset.virtual_id_prefix);
- self.dataset.to_create.push(obj);
- self.dataset.cache.push(_.clone(obj));
- ids.push(obj.id);
- return;
- case commands.UPDATE:
- obj['id'] = command[1];
- self.dataset.to_write.push(obj);
- self.dataset.cache.push(_.clone(obj));
- ids.push(obj.id);
- return;
- case commands.DELETE:
- self.dataset.to_delete.push({id: command[1]});
- return;
- case commands.LINK_TO:
- ids.push(command[1]);
- return;
- case commands.DELETE_ALL:
- self.dataset.delete_all = true;
- return;
- }
- });
- this._super(ids);
- this.dataset.set_ids(ids);
- } else if (value.length >= 1 && typeof(value[0]) === "object") {
- var ids = [];
- this.dataset.delete_all = true;
- _.each(value, function(command) {
- var obj = {values: command};
- obj['id'] = _.uniqueId(self.dataset.virtual_id_prefix);
- self.dataset.to_create.push(obj);
- self.dataset.cache.push(_.clone(obj));
- ids.push(obj.id);
- });
- this._super(ids);
- this.dataset.set_ids(ids);
- } else {
- this._super(value);
- this.dataset.reset_ids(value);
- }
- if (this.dataset.index === null && this.dataset.ids.length > 0) {
- this.dataset.index = 0;
- }
- $.when(this.is_started).then(function() {
- self.reload_current_view();
- });
- },
- get_value: function() {
- var self = this;
- if (!this.dataset)
- return [];
- var val = this.dataset.delete_all ? [commands.delete_all()] : [];
- val = val.concat(_.map(this.dataset.ids, function(id) {
- var alter_order = _.detect(self.dataset.to_create, function(x) {return x.id === id;});
- if (alter_order) {
- return commands.create(alter_order.values);
- }
- alter_order = _.detect(self.dataset.to_write, function(x) {return x.id === id;});
- if (alter_order) {
- return commands.update(alter_order.id, alter_order.values);
- }
- return commands.link_to(id);
- }));
- return val.concat(_.map(
- this.dataset.to_delete, function(x) {
- return commands['delete'](x.id);}));
- },
- save_form_view: function() {
- if (this.viewmanager && this.viewmanager.views && this.viewmanager.active_view &&
- this.viewmanager.views[this.viewmanager.active_view] &&
- this.viewmanager.views[this.viewmanager.active_view].controller) {
- var view = this.viewmanager.views[this.viewmanager.active_view].controller;
- if (this.viewmanager.active_view === "form") {
- var res = view.do_save();
- if (res === false) {
- // ignore
- } else if (res.isRejected()) {
- throw "Save or create on one2many dataset is not supposed to fail.";
- } else if (!res.isResolved()) {
- throw "Asynchronous get_value() is not supported in form view.";
- }
- return res;
- }
- }
- return false;
- },
- is_valid: function() {
- this.validate();
- return this._super();
- },
- validate: function() {
- this.invalid = false;
- var self = this;
- var view = self.viewmanager.views[self.viewmanager.active_view].controller;
- if (self.viewmanager.active_view === "form") {
- for (var f in view.fields) {
- f = view.fields[f];
- if (!f.is_valid()) {
- this.invalid = true;
- return;
- }
- }
- }
- },
- is_dirty: function() {
- this.save_form_view();
- return this._super();
- },
- update_dom: function() {
- this._super.apply(this, arguments);
- this.$element.toggleClass('disabled', this.readonly);
- }
-});
-
-openerp.base.form.One2ManyDataSet = openerp.base.BufferedDataSet.extend({
- get_context: function() {
- this.context = this.o2m.build_context();
- return this.context;
- }
-});
-
-openerp.base.form.One2ManyFormView = openerp.base.FormView.extend({
-
-});
-
-openerp.base.form.One2ManyListView = openerp.base.ListView.extend({
- do_add_record: function () {
- if (this.options.editable) {
- this._super.apply(this, arguments);
- } else {
- var self = this;
- var pop = new openerp.base.form.SelectCreatePopup(this);
- pop.select_element(self.o2m.field.relation,{
- initial_view: "form",
- alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined,
- create_function: function(data) {
- return self.o2m.dataset.create(data, function(r) {
- self.o2m.dataset.set_ids(self.o2m.dataset.ids.concat([r.result]));
- self.o2m.dataset.on_change();
- });
- },
- parent_view: self.o2m.view
- }, self.o2m.build_domain(), self.o2m.build_context());
- pop.on_select_elements.add_last(function() {
- self.o2m.reload_current_view();
- });
- }
- },
- do_activate_record: function(index, id) {
- var self = this;
- var pop = new openerp.base.form.FormOpenPopup(self.o2m.view);
- pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(),{
- auto_write: false,
- alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined,
- parent_view: self.o2m.view,
- read_function: function() {
- return self.o2m.dataset.read_ids.apply(self.o2m.dataset, arguments);
- }
- });
- pop.on_write.add(function(id, data) {
- self.o2m.dataset.write(id, data, {}, function(r) {
- self.o2m.reload_current_view();
- });
- });
- }
-});
-
-openerp.base.form.FieldMany2Many = openerp.base.form.Field.extend({
- multi_selection: false,
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldMany2Many";
- this.list_id = _.uniqueId("many2many");
- this.is_started = $.Deferred();
- },
- start: function() {
- this._super.apply(this, arguments);
-
- var self = this;
-
- this.dataset = new openerp.base.form.Many2ManyDataSet(this, this.field.relation);
- this.dataset.m2m = this;
- this.dataset.on_unlink.add_last(function(ids) {
- self.on_ui_change();
- });
-
- this.list_view = new openerp.base.form.Many2ManyListView(this, this.list_id, this.dataset, false, {
- 'addable': 'Add',
- 'selectable': self.multi_selection
- });
- this.list_view.m2m_field = this;
- this.list_view.on_loaded.add_last(function() {
- self.is_started.resolve();
- });
- setTimeout(function () {
- self.list_view.start();
- }, 0);
- },
- set_value: function(value) {
- value = value || [];
- if (value.length >= 1 && value[0] instanceof Array) {
- value = value[0][2];
- }
- this._super(value);
- this.dataset.set_ids(value);
- var self = this;
- $.when(this.is_started).then(function() {
- self.list_view.reload_content();
- });
- },
- get_value: function() {
- return [commands.replace_with(this.dataset.ids)];
- },
- validate: function() {
- this.invalid = false;
- // TODO niv
- }
-});
-
-openerp.base.form.Many2ManyDataSet = openerp.base.DataSetStatic.extend({
- get_context: function() {
- this.context = this.m2m.build_context();
- return this.context;
- }
-});
-
-openerp.base.form.Many2ManyListView = openerp.base.ListView.extend({
- do_add_record: function () {
- var pop = new openerp.base.form.SelectCreatePopup(this);
- pop.select_element(this.model, {},
- new openerp.base.CompoundDomain(this.m2m_field.build_domain(), ["!", ["id", "in", this.m2m_field.dataset.ids]]),
- this.m2m_field.build_context());
- var self = this;
- pop.on_select_elements.add(function(element_ids) {
- _.each(element_ids, function(element_id) {
- if(! _.detect(self.dataset.ids, function(x) {return x == element_id;})) {
- self.dataset.set_ids([].concat(self.dataset.ids, [element_id]));
- self.m2m_field.on_ui_change();
- self.reload_content();
- }
- });
- });
- },
- do_activate_record: function(index, id) {
- var self = this;
- var pop = new openerp.base.form.FormOpenPopup(this);
- pop.show_element(this.dataset.model, id, this.m2m_field.build_context(), {});
- pop.on_write_completed.add_last(function() {
- self.reload_content();
- });
- }
-});
-
-openerp.base.form.SelectCreatePopup = openerp.base.OldWidget.extend({
- identifier_prefix: "selectcreatepopup",
- template: "SelectCreatePopup",
- /**
- * options:
- * - initial_ids
- * - initial_view: form or search (default search)
- * - disable_multiple_selection
- * - alternative_form_view
- * - create_function (defaults to a naive saving behavior)
- * - parent_view
- */
- select_element: function(model, options, domain, context) {
- var self = this;
- this.model = model;
- this.domain = domain || [];
- this.context = context || {};
- this.options = _.defaults(options || {}, {"initial_view": "search", "create_function": function() {
- return self.create_row.apply(self, arguments);
- }});
- this.initial_ids = this.options.initial_ids;
- this.created_elements = [];
- openerp.base.form.dialog(this.render(), {close:function() {
- self.check_exit();
- }});
- this.start();
- },
- start: function() {
- this._super();
- this.dataset = new openerp.base.ReadOnlyDataSetSearch(this, this.model,
- this.context);
- this.dataset.parent_view = this.options.parent_view;
- if (this.options.initial_view == "search") {
- this.setup_search_view();
- } else { // "form"
- this.new_object();
- }
- },
- setup_search_view: function() {
- var self = this;
- if (this.searchview) {
- this.searchview.stop();
- }
- this.searchview = new openerp.base.SearchView(this,
- this.element_id + "_search", this.dataset, false, {
- "selectable": !this.options.disable_multiple_selection,
- "deletable": false
- });
- this.searchview.on_search.add(function(domains, contexts, groupbys) {
- if (self.initial_ids) {
- self.view_list.do_search.call(self, domains.concat([[["id", "in", self.initial_ids]], self.domain]),
- contexts, groupbys);
- self.initial_ids = undefined;
- } else {
- self.view_list.do_search.call(self, domains.concat([self.domain]), contexts, groupbys);
- }
- });
- this.searchview.on_loaded.add_last(function () {
- var $buttons = self.searchview.$element.find(".oe_search-view-buttons");
- $buttons.append(QWeb.render("SelectCreatePopup.search.buttons"));
- var $cbutton = $buttons.find(".oe_selectcreatepopup-search-close");
- $cbutton.click(function() {
- self.stop();
- });
- var $sbutton = $buttons.find(".oe_selectcreatepopup-search-select");
- if(self.options.disable_multiple_selection) {
- $sbutton.hide();
- }
- $sbutton.click(function() {
- self.on_select_elements(self.selected_ids);
- self.stop();
- });
- self.view_list = new openerp.base.form.SelectCreateListView(self,
- self.element_id + "_view_list", self.dataset, false,
- {'deletable': false});
- self.view_list.popup = self;
- self.view_list.do_show();
- self.view_list.start().then(function() {
- self.searchview.do_search();
- });
- });
- this.searchview.start();
- },
- create_row: function(data) {
- var self = this;
- var wdataset = new openerp.base.DataSetSearch(this, this.model, this.context, this.domain);
- wdataset.parent_view = this.options.parent_view;
- return wdataset.create(data);
- },
- on_select_elements: function(element_ids) {
- },
- on_click_element: function(ids) {
- this.selected_ids = ids || [];
- if(this.selected_ids.length > 0) {
- this.$element.find(".oe_selectcreatepopup-search-select").removeAttr('disabled');
- } else {
- this.$element.find(".oe_selectcreatepopup-search-select").attr('disabled', "disabled");
- }
- },
- new_object: function() {
- var self = this;
- if (this.searchview) {
- this.searchview.hide();
- }
- if (this.view_list) {
- this.view_list.$element.hide();
- }
- this.dataset.index = null;
- this.view_form = new openerp.base.FormView(this, this.element_id + "_view_form", this.dataset, false);
- if (this.options.alternative_form_view) {
- this.view_form.set_embedded_view(this.options.alternative_form_view);
- }
- this.view_form.start();
- this.view_form.on_loaded.add_last(function() {
- var $buttons = self.view_form.$element.find(".oe_form_buttons");
- $buttons.html(QWeb.render("SelectCreatePopup.form.buttons", {widget:self}));
- var $nbutton = $buttons.find(".oe_selectcreatepopup-form-save-new");
- $nbutton.click(function() {
- self._created = $.Deferred().then(function() {
- self._created = undefined;
- self.view_form.on_button_new();
- });
- self.view_form.do_save();
- });
- var $nbutton = $buttons.find(".oe_selectcreatepopup-form-save");
- $nbutton.click(function() {
- self._created = $.Deferred().then(function() {
- self._created = undefined;
- self.check_exit();
- });
- self.view_form.do_save();
- });
- var $cbutton = $buttons.find(".oe_selectcreatepopup-form-close");
- $cbutton.click(function() {
- self.check_exit();
- });
- });
- this.dataset.on_create.add(function(data) {
- self.options.create_function(data).then(function(r) {
- self.created_elements.push(r.result);
- if (self._created) {
- self._created.resolve();
- }
- });
- });
- this.view_form.do_show();
- },
- check_exit: function() {
- if (this.created_elements.length > 0) {
- this.on_select_elements(this.created_elements);
- }
- this.stop();
- }
-});
-
-openerp.base.form.SelectCreateListView = openerp.base.ListView.extend({
- do_add_record: function () {
- this.popup.new_object();
- },
- select_record: function(index) {
- this.popup.on_select_elements([this.dataset.ids[index]]);
- this.popup.stop();
- },
- do_select: function(ids, records) {
- this._super(ids, records);
- this.popup.on_click_element(ids);
- }
-});
-
-openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({
- identifier_prefix: "formopenpopup",
- template: "FormOpenPopup",
- /**
- * options:
- * - alternative_form_view
- * - auto_write (default true)
- * - read_function
- * - parent_view
- */
- show_element: function(model, row_id, context, options) {
- this.model = model;
- this.row_id = row_id;
- this.context = context || {};
- this.options = _.defaults(options || {}, {"auto_write": true});
- jQuery(this.render()).dialog({title: '',
- modal: true,
- width: 960,
- height: 600});
- this.start();
- },
- start: function() {
- this._super();
- this.dataset = new openerp.base.form.FormOpenDataset(this, this.model, this.context);
- this.dataset.fop = this;
- this.dataset.ids = [this.row_id];
- this.dataset.index = 0;
- this.dataset.parent_view = this.options.parent_view;
- this.setup_form_view();
- },
- on_write: function(id, data) {
- this.stop();
- if (!this.options.auto_write)
- return;
- var self = this;
- var wdataset = new openerp.base.DataSetSearch(this, this.model, this.context, this.domain);
- wdataset.parent_view = this.options.parent_view;
- wdataset.write(id, data, {}, function(r) {
- self.on_write_completed();
- });
- },
- on_write_completed: function() {},
- setup_form_view: function() {
- var self = this;
- this.view_form = new openerp.base.FormView(this, this.element_id + "_view_form", this.dataset, false);
- if (this.options.alternative_form_view) {
- this.view_form.set_embedded_view(this.options.alternative_form_view);
- }
- this.view_form.start();
- this.view_form.on_loaded.add_last(function() {
- var $buttons = self.view_form.$element.find(".oe_form_buttons");
- $buttons.html(QWeb.render("FormOpenPopup.form.buttons"));
- var $nbutton = $buttons.find(".oe_formopenpopup-form-save");
- $nbutton.click(function() {
- self.view_form.do_save();
- });
- var $cbutton = $buttons.find(".oe_formopenpopup-form-close");
- $cbutton.click(function() {
- self.stop();
- });
- self.view_form.do_show();
- });
- this.dataset.on_write.add(this.on_write);
- }
-});
-
-openerp.base.form.FormOpenDataset = openerp.base.ReadOnlyDataSetSearch.extend({
- read_ids: function() {
- if (this.fop.options.read_function) {
- return this.fop.options.read_function.apply(null, arguments);
- } else {
- return this._super.apply(this, arguments);
- }
- }
-});
-
-openerp.base.form.FieldReference = openerp.base.form.Field.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldReference";
- this.fields_view = {
- fields: {
- selection: {
- selection: view.fields_view.fields[this.name].selection
- },
- m2o: {
- relation: null
- }
- }
- }
- this.get_fields_values = view.get_fields_values;
- this.do_onchange = this.on_form_changed = this.on_nop;
- this.widgets = {};
- this.fields = {};
- this.selection = new openerp.base.form.FieldSelection(this, { attrs: {
- name: 'selection',
- widget: 'selection'
- }});
- this.selection.on_value_changed.add_last(this.on_selection_changed);
- this.m2o = new openerp.base.form.FieldMany2One(this, { attrs: {
- name: 'm2o',
- widget: 'many2one'
- }});
- },
- on_nop: function() {
- },
- on_selection_changed: function() {
- this.m2o.field.relation = this.selection.get_value();
- this.m2o.set_value(null);
- },
- start: function() {
- this._super();
- this.selection.start();
- this.m2o.start();
- },
- is_valid: function() {
- return this.required === false || typeof(this.get_value()) === 'string';
- },
- is_dirty: function() {
- return this.selection.is_dirty() || this.m2o.is_dirty();
- },
- set_value: function(value) {
- this._super(value);
- if (typeof(value) === 'string') {
- var vals = value.split(',');
- this.selection.set_value(vals[0]);
- this.m2o.set_value(parseInt(vals[1], 10));
- }
- },
- get_value: function() {
- var model = this.selection.get_value(),
- id = this.m2o.get_value();
- if (typeof(model) === 'string' && typeof(id) === 'number') {
- return model + ',' + id;
- } else {
- return false;
- }
- }
-});
-
-openerp.base.form.FieldBinary = openerp.base.form.Field.extend({
- init: function(view, node) {
- this._super(view, node);
- this.iframe = this.element_id + '_iframe';
- this.binary_value = false;
- },
- start: function() {
- this._super.apply(this, arguments);
- this.$element.find('input.oe-binary-file').change(this.on_file_change);
- this.$element.find('button.oe-binary-file-save').click(this.on_save_as);
- this.$element.find('.oe-binary-file-clear').click(this.on_clear);
- },
- update_dom: function() {
- this._super.apply(this, arguments);
- this.$element.find('.oe-binary').toggle(!this.readonly);
- },
- human_filesize : function(size) {
- var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
- var i = 0;
- while (size >= 1024) {
- size /= 1024;
- ++i;
- }
- return size.toFixed(2) + ' ' + units[i];
- },
- on_file_change: function(e) {
- // TODO: on modern browsers, we could directly read the file locally on client ready to be used on image cropper
- // http://www.html5rocks.com/tutorials/file/dndfiles/
- // http://deepliquid.com/projects/Jcrop/demos.php?demo=handler
- window[this.iframe] = this.on_file_uploaded;
- if ($(e.target).val() != '') {
- this.$element.find('form.oe-binary-form input[name=session_id]').val(this.session.session_id);
- this.$element.find('form.oe-binary-form').submit();
- this.toggle_progress();
- }
- },
- toggle_progress: function() {
- this.$element.find('.oe-binary-progress, .oe-binary').toggle();
- },
- on_file_uploaded: function(size, name, content_type, file_base64) {
- delete(window[this.iframe]);
- if (size === false) {
- this.notification.warn("File Upload", "There was a problem while uploading your file");
- // TODO: use openerp web crashmanager
- this.log("Error while uploading file : ", name);
- } else {
- this.on_file_uploaded_and_valid.apply(this, arguments);
- this.on_ui_change();
- }
- this.toggle_progress();
- },
- on_file_uploaded_and_valid: function(size, name, content_type, file_base64) {
- },
- on_save_as: function() {
- if (!this.view.datarecord.id) {
- this.notification.warn("Can't save file", "The record has not yet been saved");
- } else {
- var url = '/base/binary/saveas?session_id=' + this.session.session_id + '&model=' +
- this.view.dataset.model +'&id=' + (this.view.datarecord.id || '') + '&field=' + this.name +
- '&fieldname=' + (this.node.attrs.filename || '') + '&t=' + (new Date().getTime())
- window.open(url);
- }
- },
- on_clear: function() {
- if (this.value !== false) {
- this.value = false;
- this.binary_value = false;
- this.on_ui_change();
- }
- return false;
- }
-});
-
-openerp.base.form.FieldBinaryFile = openerp.base.form.FieldBinary.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldBinaryFile";
- },
- set_value: function(value) {
- this._super.apply(this, arguments);
- var show_value = (value != null && value !== false) ? value : '';
- this.$element.find('input').eq(0).val(show_value);
- },
- on_file_uploaded_and_valid: function(size, name, content_type, file_base64) {
- this.value = file_base64;
- this.binary_value = true;
- var show_value = this.human_filesize(size);
- this.$element.find('input').eq(0).val(show_value);
- this.set_filename(name);
- },
- set_filename: function(value) {
- var filename = this.node.attrs.filename;
- if (this.view.fields[filename]) {
- this.view.fields[filename].set_value(value);
- this.view.fields[filename].on_ui_change();
- }
- },
- on_clear: function() {
- this._super.apply(this, arguments);
- this.$element.find('input').eq(0).val('');
- this.set_filename('');
- }
-});
-
-openerp.base.form.FieldBinaryImage = openerp.base.form.FieldBinary.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldBinaryImage";
- },
- start: function() {
- this._super.apply(this, arguments);
- this.$image = this.$element.find('img.oe-binary-image');
- },
- set_value: function(value) {
- this._super.apply(this, arguments);
- this.set_image_maxwidth();
- var url = '/base/binary/image?session_id=' + this.session.session_id + '&model=' +
- this.view.dataset.model +'&id=' + (this.view.datarecord.id || '') + '&field=' + this.name + '&t=' + (new Date().getTime())
- this.$image.attr('src', url);
- },
- set_image_maxwidth: function() {
- this.$image.css('max-width', this.$element.width());
- },
- on_file_change: function() {
- this.set_image_maxwidth();
- this._super.apply(this, arguments);
- },
- on_file_uploaded_and_valid: function(size, name, content_type, file_base64) {
- this.value = file_base64;
- this.binary_value = true;
- this.$image.attr('src', 'data:' + (content_type || 'image/png') + ';base64,' + file_base64);
- },
- on_clear: function() {
- this._super.apply(this, arguments);
- this.$image.attr('src', '/base/static/src/img/placeholder.png');
- }
-});
-
-/**
- * Registry of form widgets, called by :js:`openerp.base.FormView`
- */
-openerp.base.form.widgets = new openerp.base.Registry({
- 'frame' : 'openerp.base.form.WidgetFrame',
- 'group' : 'openerp.base.form.WidgetFrame',
- 'notebook' : 'openerp.base.form.WidgetNotebook',
- 'separator' : 'openerp.base.form.WidgetSeparator',
- 'label' : 'openerp.base.form.WidgetLabel',
- 'button' : 'openerp.base.form.WidgetButton',
- 'char' : 'openerp.base.form.FieldChar',
- 'email' : 'openerp.base.form.FieldEmail',
- 'url' : 'openerp.base.form.FieldUrl',
- 'text' : 'openerp.base.form.FieldText',
- 'text_wiki' : 'openerp.base.form.FieldText',
- 'date' : 'openerp.base.form.FieldDate',
- 'datetime' : 'openerp.base.form.FieldDatetime',
- 'selection' : 'openerp.base.form.FieldSelection',
- 'many2one' : 'openerp.base.form.FieldMany2One',
- 'many2many' : 'openerp.base.form.FieldMany2Many',
- 'one2many' : 'openerp.base.form.FieldOne2Many',
- 'one2many_list' : 'openerp.base.form.FieldOne2Many',
- 'reference' : 'openerp.base.form.FieldReference',
- 'boolean' : 'openerp.base.form.FieldBoolean',
- 'float' : 'openerp.base.form.FieldFloat',
- 'integer': 'openerp.base.form.FieldFloat',
- 'float_time': 'openerp.base.form.FieldFloat',
- 'progressbar': 'openerp.base.form.FieldProgressBar',
- 'image': 'openerp.base.form.FieldBinaryImage',
- 'binary': 'openerp.base.form.FieldBinaryFile'
-});
-
-};
-
-// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
diff --git a/addons/base/static/src/js/formats.js b/addons/base/static/src/js/formats.js
deleted file mode 100644
index 625868eee75..00000000000
--- a/addons/base/static/src/js/formats.js
+++ /dev/null
@@ -1,197 +0,0 @@
-
-openerp.base.formats = function(openerp) {
-
-/**
- * Formats a single atomic value based on a field descriptor
- *
- * @param {Object} value read from OpenERP
- * @param {Object} descriptor union of orm field and view field
- * @param {Object} [descriptor.widget] widget to use to display the value
- * @param {Object} descriptor.type fallback if no widget is provided, or if the provided widget is unknown
- * @param {Object} [descriptor.digits] used for the formatting of floats
- * @param {String} [value_if_empty=''] returned if the ``value`` argument is considered empty
- */
-openerp.base.format_value = function (value, descriptor, value_if_empty) {
- // If NaN value, display as with a `false` (empty cell)
- if (typeof value === 'number' && isNaN(value)) {
- value = false;
- }
- switch (value) {
- case false:
- case Infinity:
- case -Infinity:
- return value_if_empty === undefined ? '' : value_if_empty;
- }
- switch (descriptor.widget || descriptor.type) {
- case 'integer':
- return _.sprintf('%d', value);
- case 'float':
- var precision = descriptor.digits ? descriptor.digits[1] : 2;
- var int_part = Math.floor(value);
- var dec_part = Math.abs(Math.floor((value % 1) * Math.pow(10, precision)));
- return _.sprintf('%d%s%d',
- int_part,
- openerp.base._t.database.parameters.decimal_point, dec_part);
- case 'float_time':
- return _.sprintf("%02d:%02d",
- Math.floor(value),
- Math.round((value % 1) * 60));
- case 'progressbar':
- return _.sprintf(
- '<progress value="%.2f" max="100.0">%.2f%%</progress>',
- value, value);
- case 'many2one':
- // name_get value format
- return value[1];
- case 'datetime':
- if (typeof(value) == "string")
- value = openerp.base.auto_str_to_date(value);
- try {
- return value.toString(_.sprintf("%s %s", Date.CultureInfo.formatPatterns.shortDate,
- Date.CultureInfo.formatPatterns.longTime));
- } catch (e) {
- return value.format("%m/%d/%Y %H:%M:%S");
- }
- return value;
- case 'date':
- if (typeof(value) == "string")
- value = openerp.base.auto_str_to_date(value);
- try {
- return value.toString(Date.CultureInfo.formatPatterns.shortDate);
- } catch (e) {
- return value.format("%m/%d/%Y");
- }
- case 'time':
- if (typeof(value) == "string")
- value = openerp.base.auto_str_to_date(value);
- try {
- return value.toString(Date.CultureInfo.formatPatterns.longTime);
- } catch (e) {
- return value.format("%H:%M:%S");
- }
- default:
- return value;
- }
-};
-
-openerp.base.parse_value = function (value, descriptor, value_if_empty) {
- switch (value) {
- case false:
- case "":
- return value_if_empty === undefined ? false : value_if_empty;
- }
- switch (descriptor.widget || descriptor.type) {
- case 'integer':
- var tmp = Number(value);
- if (isNaN(tmp))
- throw value + " is not a correct integer";
- return tmp;
- case 'float':
- var tmp = Number(value);
- if (!isNaN(tmp))
- return tmp;
- tmp = value.replace(openerp.base._t.database.parameters.decimal_point, ".");
- var tmp2 = tmp;
- do {
- tmp = tmp2;
- tmp2 = tmp.replace(openerp.base._t.database.parameters.thousands_sep, "");
- } while(tmp !== tmp2);
- tmp = Number(tmp);
- if (isNaN(tmp))
- throw value + " is not a correct float";
- return tmp;
- case 'float_time':
- var tmp = value.split(":");
- if (tmp.length != 2)
- throw value + " is not a correct float_time";
- var tmp1 = openerp.base.parse_value(tmp[0], {type: "integer"});
- var tmp2 = openerp.base.parse_value(tmp[1], {type: "integer"});
- return tmp1 + (tmp2 / 60);
- case 'progressbar':
- return openerp.base.parse_value(value, {type: "float"});
- case 'datetime':
- var tmp = Date.parseExact(value, _.sprintf("%s %s", Date.CultureInfo.formatPatterns.shortDate,
- Date.CultureInfo.formatPatterns.longTime));
- if (tmp !== null)
- return tmp;
- tmp = Date.parse(value);
- if (tmp !== null)
- return tmp;
- throw value + " is not a valid datetime";
- case 'date':
- var tmp = Date.parseExact(value, Date.CultureInfo.formatPatterns.shortDate);
- if (tmp !== null)
- return tmp;
- tmp = Date.parse(value);
- if (tmp !== null)
- return tmp;
- throw value + " is not a valid date";
- case 'time':
- var tmp = Date.parseExact(value, Date.CultureInfo.formatPatterns.longTime);
- if (tmp !== null)
- return tmp;
- tmp = Date.parse(value);
- if (tmp !== null)
- return tmp;
- throw value + " is not a valid time";
- }
- return value;
-};
-
-openerp.base.auto_str_to_date = function(value, type) {
- try {
- return openerp.base.str_to_datetime(value);
- } catch(e) {}
- try {
- return openerp.base.str_to_date(value);
- } catch(e) {}
- try {
- return openerp.base.str_to_time(value);
- } catch(e) {}
- throw "'" + value + "' is not a valid date, datetime nor time"
-};
-
-openerp.base.auto_date_to_str = function(value, type) {
- switch(type) {
- case 'datetime':
- return openerp.base.datetime_to_str(value);
- case 'date':
- return openerp.base.date_to_str(value);
- case 'time':
- return openerp.base.time_to_str(value);
- default:
- throw type + " is not convertible to date, datetime nor time"
- }
-};
-
-/**
- * Formats a provided cell based on its field type
- *
- * @param {Object} row_data record whose values should be displayed in the cell
- * @param {Object} column column descriptor
- * @param {"button"|"field"} column.tag base control type
- * @param {String} column.type widget type for a field control
- * @param {String} [column.string] button label
- * @param {String} [column.icon] button icon
- * @param {String} [value_if_empty=''] what to display if the field's value is ``false``
- */
-openerp.base.format_cell = function (row_data, column, value_if_empty) {
- var attrs = column.modifiers_for(row_data);
- if (attrs.invisible) { return ''; }
- if (column.tag === 'button') {
- return [
- '<button type="button" title="', column.string || '', '">',
- '<img src="/base/static/src/img/icons/', column.icon, '.png"',
- ' alt="', column.string || '', '"/>',
- '</button>'
- ].join('')
- }
-
- if (!row_data[column.id]) {
- return value_if_empty === undefined ? '' : value_if_empty;
- }
- return openerp.base.format_value(
- row_data[column.id].value, column, value_if_empty);
-}
-
-};
diff --git a/addons/base/static/src/js/list-editable.js b/addons/base/static/src/js/list-editable.js
deleted file mode 100644
index 1cd43fd6ea8..00000000000
--- a/addons/base/static/src/js/list-editable.js
+++ /dev/null
@@ -1,324 +0,0 @@
-/**
- * @namespace handles editability case for lists, because it depends on form and forms already depends on lists it had to be split out
- */
-openerp.base.list_editable = function (openerp) {
- var KEY_RETURN = 13,
- KEY_ESCAPE = 27;
-
- // editability status of list rows
- openerp.base.ListView.prototype.defaults.editable = null;
-
- // TODO: not sure second @lends on existing item is correct, to check
- openerp.base.ListView.include(/** @lends openerp.base.ListView# */{
- init: function () {
- var self = this;
- this._super.apply(this, arguments);
- $(this.groups).bind({
- 'edit': function (e, id, dataset) {
- self.do_edit(dataset.index, id, dataset);
- },
- 'saved': function () {
- if (self.groups.get_selection().length) {
- return;
- }
- self.compute_aggregates();
- }
- })
- },
- /**
- * Handles the activation of a record in editable mode (making a record
- * editable), called *after* the record has become editable.
- *
- * The default behavior is to setup the listview's dataset to match
- * whatever dataset was provided by the editing List
- *
- * @param {Number} index index of the record in the dataset
- * @param {Object} id identifier of the record being edited
- * @param {openerp.base.DataSet} dataset dataset in which the record is available
- */
- do_edit: function (index, id, dataset) {
- _.extend(this.dataset, dataset);
- },
- /**
- * Sets editability status for the list, based on defaults, view
- * architecture and the provided flag, if any.
- *
- * @param {Boolean} [force] forces the list to editability. Sets new row edition status to "bottom".
- */
- set_editable: function (force) {
- // If ``force``, set editability to bottom
- // otherwise rely on view default
- // view' @editable is handled separately as we have not yet
- // fetched and processed the view at this point.
- this.options.editable = (
- (force && "bottom")
- || this.defaults.editable);
- },
- /**
- * Replace do_actual_search to handle editability process
- */
- do_actual_search: function (results) {
- this.set_editable(results.context['set_editable']);
- this._super(results);
- },
- /**
- * Replace do_add_record to handle editability (and adding new record
- * as an editable row at the top or bottom of the list)
- */
- do_add_record: function () {
- if (this.options.editable) {
- this.groups.new_record();
- } else {
- this._super();
- }
- },
- on_loaded: function (data, grouped) {
- // tree/@editable takes priority on everything else if present.
- this.options.editable = data.fields_view.arch.attrs.editable || this.options.editable;
- return this._super(data, grouped);
- }
- });
-
- openerp.base.ListView.Groups.include(/** @lends openerp.base.ListView.Groups# */{
- passtrough_events: openerp.base.ListView.Groups.prototype.passtrough_events + " edit saved",
- new_record: function () {
- // TODO: handle multiple children
- this.children[null].new_record();
- }
- });
-
- openerp.base.ListView.List.include(/** @lends openerp.base.ListView.List */{
- row_clicked: function (event) {
- if (!this.options.editable) {
- return this._super(event);
- }
- this.edit_record($(event.currentTarget).data('id'));
- },
- /**
- * Checks if a record is being edited, and if so cancels it
- */
- cancel_pending_edition: function () {
- var self = this, cancelled = $.Deferred();
- if (!this.edition) {
- cancelled.resolve();
- return cancelled.promise();
- }
-
- if (this.edition_id != null) {
- this.reload_record(self.records.get(this.edition_id)).then(function () {
- cancelled.resolve();
- });
- } else {
- cancelled.resolve();
- }
- cancelled.then(function () {
- self.edition_form.stop();
- self.edition_form.$element.remove();
- delete self.edition_form;
- delete self.edition_id;
- delete self.edition;
- });
- return cancelled.promise();
- },
- /**
- * Adapts this list's view description to be suitable to the inner form
- * view of a row being edited.
- *
- * @returns {Object} fields_view_get's view section suitable for putting into form view of editable rows.
- */
- get_form_fields_view: function () {
- // deep copy of view
- var view = $.extend(true, {}, this.group.view.fields_view);
- _(view.arch.children).each(function (widget) {
- widget.attrs.nolabel = true;
- if (widget.tag === 'button') {
- delete widget.attrs.string;
- }
- });
- view.arch.attrs.col = 2 * view.arch.children.length;
- return view;
- },
- render_row_as_form: function (row) {
- var self = this;
- this.cancel_pending_edition().then(function () {
- var record_id = $(row).data('id');
- var $new_row = $('<tr>', {
- id: _.uniqueId('oe-editable-row-'),
- 'data-id': record_id,
- 'class': $(row).attr('class') + ' oe_forms',
- click: function (e) {e.stopPropagation();}
- })
- .delegate('button.oe-edit-row-save', 'click', function () {
- self.save_row();
- })
- .delegate('button.oe-edit-row-cancel', 'click', function () {
- self.cancel_edition();
- })
- .delegate('button', 'keyup', function (e) {
- e.stopImmediatePropagation();
- })
- .keyup(function (e) {
- switch (e.which) {
- case KEY_RETURN:
- self.save_row(true);
- break;
- case KEY_ESCAPE:
- self.cancel_edition();
- break;
- default:
- return;
- }
- });
- if (row) {
- $new_row.replaceAll(row);
- } else if (self.options.editable === 'top') {
- self.$current.prepend($new_row);
- } else if (self.options.editable) {
- self.$current.append($new_row);
- }
- self.edition = true;
- self.edition_id = record_id;
- self.edition_form = _.extend(new openerp.base.FormView(
- self, $new_row.attr('id'), self.dataset, false), {
- template: 'ListView.row.form',
- registry: openerp.base.list.form.widgets
- });
- $.when(self.edition_form.on_loaded({fields_view: self.get_form_fields_view()})).then(function () {
- // put in $.when just in case FormView.on_loaded becomes asynchronous
- $new_row.find('td')
- .addClass('oe-field-cell')
- .removeAttr('width')
- .end()
- .find('td:first').removeClass('oe-field-cell').end()
- .find('td:last').removeClass('oe-field-cell').end();
- // pad in case of groupby
- _(self.columns).each(function (column) {
- if (column.meta) {
- $new_row.prepend('<td>');
- }
- });
-
- self.edition_form.do_show();
- });
- });
- },
- handle_onwrite: function (source_record_id) {
- var self = this;
- var on_write_callback = self.view.fields_view.arch.attrs.on_write;
- if (!on_write_callback) { return; }
- this.dataset.call(on_write_callback, [source_record_id], function (ids) {
- _(ids).each(function (id) {
- var record = self.records.get(id);
- if (!record) {
- // insert after the source record
- var index = self.records.indexOf(
- self.records.get(source_record_id)) + 1;
- record = new openerp.base.list.Record({id: id});
- self.records.add(record, {at: index});
- self.dataset.ids.splice(index, 0, id);
- }
- self.reload_record(record);
- });
- });
- },
- /**
- * Saves the current row, and triggers the edition of its following
- * sibling if asked.
- *
- * @param {Boolean} [edit_next=false] should the next row become editable
- */
- save_row: function (edit_next) {
- var self = this;
- this.edition_form.do_save(function (result) {
- if (result.created && !self.edition_id) {
- self.records.add({id: result.result},
- {at: self.options.editable === 'top' ? 0 : null});
- self.edition_id = result.result;
- }
- var edited_record = self.records.get(self.edition_id),
- next_record = self.records.at(
- self.records.indexOf(edited_record) + 1);
-
- self.handle_onwrite(self.edition_id);
- self.cancel_pending_edition().then(function () {
- $(self).trigger('saved', [self.dataset]);
- if (!edit_next) {
- return;
- }
- if (result.created) {
- self.new_record();
- return;
- }
- var next_record_id;
- if (next_record) {
- next_record_id = next_record.get('id');
- self.dataset.index = _(self.dataset.ids)
- .indexOf(next_record_id);
- } else {
- self.dataset.index = 0;
- next_record_id = self.records.at(0).get('id');
- }
- self.edit_record(next_record_id);
- });
- }, this.options.editable === 'top');
- },
- /**
- * Cancels the edition of the row for the current dataset index
- */
- cancel_edition: function () {
- this.cancel_pending_edition();
- },
- /**
- * Edits record currently selected via dataset
- */
- edit_record: function (record_id) {
- this.render_row_as_form(
- this.$current.find('[data-id=' + record_id + ']'));
- $(this).trigger(
- 'edit',
- [record_id, this.dataset]);
- },
- new_record: function () {
- this.dataset.index = null;
- this.render_row_as_form();
- }
- });
- if (!openerp.base.list) {
- openerp.base.list = {};
- }
- if (!openerp.base.list.form) {
- openerp.base.list.form = {};
- }
- openerp.base.list.form.WidgetFrame = openerp.base.form.WidgetFrame.extend({
- template: 'ListView.row.frame'
- });
- var form_widgets = openerp.base.form.widgets;
- openerp.base.list.form.widgets = form_widgets.clone({
- 'frame': 'openerp.base.list.form.WidgetFrame'
- });
- // All form widgets inherit a problematic behavior from
- // openerp.base.form.WidgetFrame: the cell itself is removed when invisible
- // whether it's @invisible or @attrs[invisible]. In list view, only the
- // former should completely remove the cell. We need to override update_dom
- // on all widgets since we can't just hit on widget itself (I think)
- var list_form_widgets = openerp.base.list.form.widgets;
- _(list_form_widgets.map).each(function (widget_path, key) {
- if (key === 'frame') { return; }
- var new_path = 'openerp.base.list.form.' + key;
-
- openerp.base.list.form[key] = (form_widgets.get_object(key)).extend({
- update_dom: function () {
- this.$element.children().css('visibility', '');
- if (this.modifiers.tree_invisible) {
- var old_invisible = this.invisible;
- this.invisible = !!this.modifiers.tree_invisible;
- this._super();
- this.invisible = old_invisible;
- } else if (this.invisible) {
- this.$element.children().css('visibility', 'hidden');
- }
- }
- });
- list_form_widgets.add(key, new_path);
- });
-};
diff --git a/addons/base/static/src/js/list.js b/addons/base/static/src/js/list.js
deleted file mode 100644
index 786c8cb2068..00000000000
--- a/addons/base/static/src/js/list.js
+++ /dev/null
@@ -1,1467 +0,0 @@
-openerp.base.list = function (openerp) {
-openerp.base.views.add('list', 'openerp.base.ListView');
-openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListView# */ {
- defaults: {
- // records can be selected one by one
- 'selectable': true,
- // list rows can be deleted
- 'deletable': true,
- // whether the column headers should be displayed
- 'header': true,
- // display addition button, with that label
- 'addable': "New",
- // whether the list view can be sorted, note that once a view has been
- // sorted it can not be reordered anymore
- 'sortable': true,
- // whether the view rows can be reordered (via vertical drag & drop)
- 'reorderable': true
- },
- /**
- * Core class for list-type displays.
- *
- * As a view, needs a number of view-related parameters to be correctly
- * instantiated, provides options and overridable methods for behavioral
- * customization.
- *
- * See constructor parameters and method documentations for information on
- * the default behaviors and possible options for the list view.
- *
- * @constructs
- * @param parent parent object
- * @param element_id the id of the DOM elements this view should link itself to
- * @param {openerp.base.DataSet} dataset the dataset the view should work with
- * @param {String} view_id the listview's identifier, if any
- * @param {Object} options A set of options used to configure the view
- * @param {Boolean} [options.selectable=true] determines whether view rows are selectable (e.g. via a checkbox)
- * @param {Boolean} [options.header=true] should the list's header be displayed
- * @param {Boolean} [options.deletable=true] are the list rows deletable
- * @param {void|String} [options.addable="New"] should the new-record button be displayed, and what should its label be. Use ``null`` to hide the button.
- * @param {Boolean} [options.sortable=true] is it possible to sort the table by clicking on column headers
- * @param {Boolean} [options.reorderable=true] is it possible to reorder list rows
- *
- * @borrows openerp.base.ActionExecutor#execute_action as #execute_action
- */
- init: function(parent, element_id, dataset, view_id, options) {
- var self = this;
- this._super(parent, element_id);
- this.set_default_options(_.extend({}, this.defaults, options || {}));
- this.dataset = dataset;
- this.model = dataset.model;
- this.view_id = view_id;
-
- this.columns = [];
-
- this.records = new Collection();
-
- this.set_groups(new openerp.base.ListView.Groups(this));
-
- if (this.dataset instanceof openerp.base.DataSetStatic) {
- this.groups.datagroup = new openerp.base.StaticDataGroup(this.dataset);
- }
-
- this.page = 0;
- this.records.bind('change', function (event, record, key) {
- if (!_(self.aggregate_columns).chain()
- .pluck('name').contains(key).value()) {
- return;
- }
- self.compute_aggregates();
- });
- },
- /**
- * Retrieves the view's number of records per page (|| section)
- *
- * options > defaults > parent.action.limit > indefinite
- *
- * @returns {Number|null}
- */
- limit: function () {
- if (this._limit === undefined) {
- this._limit = (this.options.limit
- || this.defaults.limit
- || (this.widget_parent.action || {}).limit
- || null);
- }
- return this._limit;
- },
- /**
- * Set a custom Group construct as the root of the List View.
- *
- * @param {openerp.base.ListView.Groups} groups
- */
- set_groups: function (groups) {
- var self = this;
- if (this.groups) {
- $(this.groups).unbind("selected deleted action row_link");
- delete this.groups;
- }
-
- this.groups = groups;
- $(this.groups).bind({
- 'selected': function (e, ids, records) {
- self.do_select(ids, records);
- },
- 'deleted': function (e, ids) {
- self.do_delete(ids);
- },
- 'action': function (e, action_name, id, callback) {
- self.do_button_action(action_name, id, callback);
- },
- 'row_link': function (e, id, dataset) {
- self.do_activate_record(dataset.index, id, dataset);
- }
- });
- },
- /**
- * View startup method, the default behavior is to set the ``oe-listview``
- * class on its root element and to perform an RPC load call.
- *
- * @returns {$.Deferred} loading promise
- */
- start: function() {
- this.$element.addClass('oe-listview');
- return this.reload_view(null, null, true);
- },
- /**
- * Called after loading the list view's description, sets up such things
- * as the view table's columns, renders the table itself and hooks up the
- * various table-level and row-level DOM events (action buttons, deletion
- * buttons, selection of records, [New] button, selection of a given
- * record, ...)
- *
- * Sets up the following:
- *
- * * Processes arch and fields to generate a complete field descriptor for each field
- * * Create the table itself and allocate visible columns
- * * Hook in the top-level (header) [New|Add] and [Delete] button
- * * Sets up showing/hiding the top-level [Delete] button based on records being selected or not
- * * Sets up event handlers for action buttons and per-row deletion button
- * * Hooks global callback for clicking on a row
- * * Sets up its sidebar, if any
- *
- * @param {Object} data wrapped fields_view_get result
- * @param {Object} data.fields_view fields_view_get result (processed)
- * @param {Object} data.fields_view.fields mapping of fields for the current model
- * @param {Object} data.fields_view.arch current list view descriptor
- * @param {Boolean} grouped Is the list view grouped
- */
- on_loaded: function(data, grouped) {
- var self = this;
- this.fields_view = data.fields_view;
- //this.log(this.fields_view);
- this.name = "" + this.fields_view.arch.attrs.string;
-
- this.setup_columns(this.fields_view.fields, grouped);
-
- this.$element.html(QWeb.render("ListView", this));
-
- // Head hook
- this.$element.find('.oe-list-add')
- .click(this.do_add_record)
- .attr('disabled', grouped && this.options.editable);
- this.$element.find('.oe-list-delete')
- .attr('disabled', true)
- .click(this.do_delete_selected);
- this.$element.find('thead').delegate('th.oe-sortable[data-id]', 'click', function (e) {
- e.stopPropagation();
-
- var $this = $(this);
- self.dataset.sort($this.data('id'));
- if ($this.find('span').length) {
- $this.find('span').toggleClass(
- 'ui-icon-triangle-1-s ui-icon-triangle-1-n');
- } else {
- $this.append('<span class="ui-icon ui-icon-triangle-1-s">')
- .siblings('.oe-sortable').find('span').remove();
- }
-
- self.reload_content();
- });
-
- this.$element.find('.oe-list-pager')
- .delegate('button', 'click', function () {
- var $this = $(this);
- switch ($this.data('pager-action')) {
- case 'first':
- self.page = 0; break;
- case 'last':
- self.page = Math.floor(
- self.dataset.ids.length / self.limit());
- break;
- case 'next':
- self.page += 1; break;
- case 'previous':
- self.page -= 1; break;
- }
- self.reload_content();
- }).find('.oe-pager-state')
- .click(function (e) {
- e.stopPropagation();
- var $this = $(this);
-
- var $select = $('<select>')
- .appendTo($this.empty())
- .click(function (e) {e.stopPropagation();})
- .append('<option value="80">80</option>' +
- '<option value="100">100</option>' +
- '<option value="200">200</option>' +
- '<option value="500">500</option>' +
- '<option value="NaN">Unlimited</option>')
- .change(function () {
- var val = parseInt($select.val(), 10);
- self._limit = (isNaN(val) ? null : val);
- self.page = 0;
- self.reload_content();
- })
- .val(self._limit || 'NaN');
- });
- if (!this.sidebar && this.options.sidebar && this.options.sidebar_id) {
- this.sidebar = new openerp.base.Sidebar(this, this.options.sidebar_id);
- this.sidebar.start();
- this.sidebar.add_toolbar(data.fields_view.toolbar);
- this.set_common_sidebar_sections(this.sidebar);
- }
- },
- /**
- * Configures the ListView pager based on the provided dataset's information
- *
- * Horrifying side-effect: sets the dataset's data on this.dataset?
- *
- * @param {openerp.base.DataSet} dataset
- */
- configure_pager: function (dataset) {
- this.dataset.ids = dataset.ids;
-
- var limit = this.limit(),
- total = dataset.ids.length,
- first = (this.page * limit),
- last;
- if (!limit || (total - first) < limit) {
- last = total;
- } else {
- last = first + limit;
- }
- this.$element.find('span.oe-pager-state').empty().text(_.sprintf(
- "[%d to %d] of %d", first + 1, last, total));
-
- this.$element
- .find('button[data-pager-action=first], button[data-pager-action=previous]')
- .attr('disabled', this.page === 0)
- .end()
- .find('button[data-pager-action=last], button[data-pager-action=next]')
- .attr('disabled', last === total);
- },
- /**
- * Sets up the listview's columns: merges view and fields data, move
- * grouped-by columns to the front of the columns list and make them all
- * visible.
- *
- * @param {Object} fields fields_view_get's fields section
- * @param {Boolean} [grouped] Should the grouping columns (group and count) be displayed
- */
- setup_columns: function (fields, grouped) {
- var domain_computer = openerp.base.form.compute_domain;
-
- var noop = function () { return {}; };
- var field_to_column = function (field) {
- var name = field.attrs.name;
- var column = _.extend({id: name, tag: field.tag},
- field.attrs, fields[name]);
- // modifiers computer
- if (column.modifiers) {
- var modifiers = JSON.parse(column.modifiers);
- column.modifiers_for = function (fields) {
- if (!modifiers.invisible) {
- return {};
- }
- return {
- 'invisible': domain_computer(modifiers.invisible, fields)
- };
- };
- if (modifiers['tree_invisible']) {
- column.invisible = '1';
- }
- } else {
- column.modifiers_for = noop;
- }
- return column;
- };
-
- this.columns.splice(0, this.columns.length);
- this.columns.push.apply(
- this.columns,
- _(this.fields_view.arch.children).map(field_to_column));
- if (grouped) {
- this.columns.unshift({
- id: '_group', tag: '', string: "Group", meta: true,
- modifiers_for: function () { return {}; }
- }, {
- id: '_count', tag: '', string: '#', meta: true,
- modifiers_for: function () { return {}; }
- });
- }
-
- this.visible_columns = _.filter(this.columns, function (column) {
- return column.invisible !== '1';
- });
-
- this.aggregate_columns = _(this.visible_columns)
- .map(function (column) {
- if (column.type !== 'integer' && column.type !== 'float') {
- return {};
- }
- var aggregation_func = column['group_operator'] || 'sum';
-
- return _.extend({}, column, {
- 'function': aggregation_func,
- label: column[aggregation_func]
- });
- });
- },
- /**
- * Used to handle a click on a table row, if no other handler caught the
- * event.
- *
- * The default implementation asks the list view's view manager to switch
- * to a different view (by calling
- * :js:func:`~openerp.base.ViewManager.on_mode_switch`), using the
- * provided record index (within the current list view's dataset).
- *
- * If the index is null, ``switch_to_record`` asks for the creation of a
- * new record.
- *
- * @param {Number|void} index the record index (in the current dataset) to switch to
- * @param {String} [view="form"] the view type to switch to
- */
- select_record:function (index, view) {
- view = view || 'form';
- this.dataset.index = index;
- _.delay(_.bind(function () {
- this.do_switch_view(view);
- }, this));
- },
- do_show: function () {
- this.$element.show();
- if (this.sidebar) {
- this.sidebar.$element.show();
- }
- if (this.hidden) {
- this.reload_content();
- }
- },
- do_hide: function () {
- this.$element.hide();
- if (this.sidebar) {
- this.sidebar.$element.hide();
- }
- this.hidden = true;
- },
- /**
- * Reloads the list view based on the current settings (dataset & al)
- *
- * @param {Boolean} [grouped] Should the list be displayed grouped
- * @param {Object} [context] context to send the server while loading the view
- */
- reload_view: function (grouped, context, initial) {
- var self = this;
- var callback = function (field_view_get) {
- self.on_loaded(field_view_get, grouped);
- };
- if (this.embedded_view) {
- return $.Deferred().then(callback).resolve({fields_view: this.embedded_view});
- } else {
- return this.rpc('/base/listview/load', {
- model: this.model,
- view_id: this.view_id,
- context: this.dataset.get_context(context),
- toolbar: this.options.sidebar
- }, callback);
- }
- },
- /**
- * re-renders the content of the list view
- */
- reload_content: function () {
- var self = this;
- this.records.reset();
- this.$element.find('.oe-listview-content').append(
- this.groups.render(function () {
- if (self.dataset.index == null) {
- var has_one = false;
- self.records.each(function () { has_one = true; });
- if (has_one) {
- self.dataset.index = 0;
- }
- }
- self.compute_aggregates();
- }));
- },
- /**
- * Event handler for a search, asks for the computation/folding of domains
- * and contexts (and group-by), then reloads the view's content.
- *
- * @param {Array} domains a sequence of literal and non-literal domains
- * @param {Array} contexts a sequence of literal and non-literal contexts
- * @param {Array} groupbys a sequence of literal and non-literal group-by contexts
- * @returns {$.Deferred} fold request evaluation promise
- */
- do_search: function (domains, contexts, groupbys) {
- return this.rpc('/base/session/eval_domain_and_context', {
- domains: [this.dataset.get_domain()].concat(domains),
- contexts: [this.dataset.get_context()].concat(contexts),
- group_by_seq: groupbys
- }, $.proxy(this, 'do_actual_search'));
- },
- /**
- * Handler for the result of eval_domain_and_context, actually perform the
- * searching
- *
- * @param {Object} results results of evaluating domain and process for a search
- */
- do_actual_search: function (results) {
- this.groups.datagroup = new openerp.base.DataGroup(
- this, this.model,
- results.domain,
- results.context,
- results.group_by);
- this.groups.datagroup.sort = this.dataset._sort;
-
- if (_.isEmpty(results.group_by) && !results.context['group_by_no_leaf']) {
- results.group_by = null;
- }
-
- this.reload_view(!!results.group_by, results.context).then(
- $.proxy(this, 'reload_content'));
- },
- /**
- * Handles the signal to delete lines from the records list
- *
- * @param {Array} ids the ids of the records to delete
- */
- do_delete: function (ids) {
- if (!ids.length) {
- return;
- }
- var self = this;
- return $.when(this.dataset.unlink(ids)).then(function () {
- _(ids).each(function (id) {
- self.records.remove(self.records.get(id));
- });
- self.compute_aggregates();
- });
- },
- /**
- * Handles the signal indicating that a new record has been selected
- *
- * @param {Array} ids selected record ids
- * @param {Array} records selected record values
- */
- do_select: function (ids, records) {
- this.$element.find('.oe-list-delete')
- .attr('disabled', !ids.length);
-
- if (!records.length) {
- this.compute_aggregates();
- return;
- }
- this.compute_aggregates(_(records).map(function (record) {
- return {count: 1, values: record};
- }));
- },
- /**
- * Handles action button signals on a record
- *
- * @param {String} name action name
- * @param {Object} id id of the record the action should be called on
- * @param {Function} callback should be called after the action is executed, if non-null
- */
- do_button_action: function (name, id, callback) {
- var action = _.detect(this.columns, function (field) {
- return field.name === name;
- });
- if (!action) { return; }
- this.execute_action(action, this.dataset, id, callback);
- },
- /**
- * Handles the activation of a record (clicking on it)
- *
- * @param {Number} index index of the record in the dataset
- * @param {Object} id identifier of the activated record
- * @param {openerp.base.DataSet} dataset dataset in which the record is available (may not be the listview's dataset in case of nested groups)
- */
- do_activate_record: function (index, id, dataset) {
- var self = this;
- // TODO is it needed ?
- this.dataset.read_slice([],{
- context: dataset.get_context(),
- domain: dataset.get_domain()
- }, function () {
- self.select_record(index);
- });
- },
- /**
- * Handles signal for the addition of a new record (can be a creation,
- * can be the addition from a remote source, ...)
- *
- * The default implementation is to switch to a new record on the form view
- */
- do_add_record: function () {
- this.select_record(null);
- },
- /**
- * Handles deletion of all selected lines
- */
- do_delete_selected: function () {
- this.do_delete(this.groups.get_selection().ids);
- },
- /**
- * Computes the aggregates for the current list view, either on the
- * records provided or on the records of the internal
- * :js:class:`~openerp.base.ListView.Group`, by calling
- * :js:func:`~openerp.base.ListView.group.get_records`.
- *
- * Then displays the aggregates in the table through
- * :js:method:`~openerp.base.ListView.display_aggregates`.
- *
- * @param {Array} [records]
- */
- compute_aggregates: function (records) {
- var columns = _(this.aggregate_columns).filter(function (column) {
- return column['function']; });
- if (_.isEmpty(columns)) { return; }
-
- if (_.isEmpty(records)) {
- records = this.groups.get_records();
- }
-
- var count = 0, sums = {};
- _(columns).each(function (column) {
- switch (column['function']) {
- case 'max':
- sums[column.id] = -Infinity;
- break;
- case 'min':
- sums[column.id] = Infinity;
- break;
- default:
- sums[column.id] = 0;
- }
- });
- _(records).each(function (record) {
- count += record.count || 1;
- _(columns).each(function (column) {
- var field = column.id,
- value = record.values[field];
- switch (column['function']) {
- case 'sum':
- sums[field] += value;
- break;
- case 'avg':
- sums[field] += record.count * value;
- break;
- case 'min':
- if (sums[field] > value) {
- sums[field] = value;
- }
- break;
- case 'max':
- if (sums[field] < value) {
- sums[field] = value;
- }
- break;
- }
- });
- });
-
- var aggregates = {};
- _(columns).each(function (column) {
- var field = column.id;
- switch (column['function']) {
- case 'avg':
- aggregates[field] = {value: sums[field] / count};
- break;
- default:
- aggregates[field] = {value: sums[field]};
- }
- });
-
- this.display_aggregates(aggregates);
- },
- display_aggregates: function (aggregation) {
- var $footer_cells = this.$element.find('.oe-list-footer');
- _(this.aggregate_columns).each(function (column) {
- if (!column['function']) {
- return;
- }
-
- $footer_cells.filter(_.sprintf('[data-field=%s]', column.id))
- .html(openerp.base.format_cell(aggregation, column));
- });
- },
- get_selected_ids: function() {
- var ids = this.groups.get_selection().ids;
- return ids;
- }
-});
-openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.ListView.List# */{
- /**
- * List display for the ListView, handles basic DOM events and transforms
- * them in the relevant higher-level events, to which the list view (or
- * other consumers) can subscribe.
- *
- * Events on this object are registered via jQuery.
- *
- * Available events:
- *
- * `selected`
- * Triggered when a row is selected (using check boxes), provides an
- * array of ids of all the selected records.
- * `deleted`
- * Triggered when deletion buttons are hit, provide an array of ids of
- * all the records being marked for suppression.
- * `action`
- * Triggered when an action button is clicked, provides two parameters:
- *
- * * The name of the action to execute (as a string)
- * * The id of the record to execute the action on
- * `row_link`
- * Triggered when a row of the table is clicked, provides the index (in
- * the rows array) and id of the selected record to the handle function.
- *
- * @constructs
- * @param {Object} opts display options, identical to those of :js:class:`openerp.base.ListView`
- */
- init: function (group, opts) {
- var self = this;
- this.group = group;
- this.view = group.view;
- this.session = this.view.session;
-
- this.options = opts.options;
- this.columns = opts.columns;
- this.dataset = opts.dataset;
- this.records = opts.records;
-
- this.record_callbacks = {
- 'remove': function (event, record) {
- var $row = self.$current.find(
- '[data-id=' + record.get('id') + ']');
- var index = $row.data('index');
- $row.remove();
- self.refresh_zebra(index);
- },
- 'reset': $.proxy(this, 'on_records_reset'),
- 'change': function (event, record) {
- var $row = self.$current.find('[data-id=' + record.get('id') + ']');
- $row.replaceWith(self.render_record(record));
- },
- 'add': function (ev, records, record, index) {
- var $new_row = $('<tr>').attr({
- 'data-id': record.get('id')
- });
-
- if (index === 0) {
- $new_row.prependTo(self.$current);
- } else {
- var previous_record = records.at(index-1),
- $previous_sibling = self.$current.find(
- '[data-id=' + previous_record.get('id') + ']');
- $new_row.insertAfter($previous_sibling);
- }
-
- self.refresh_zebra(index, 1);
- }
- };
- _(this.record_callbacks).each(function (callback, event) {
- this.records.bind(event, callback);
- }, this);
-
- this.$_element = $('<tbody class="ui-widget-content">')
- .appendTo(document.body)
- .delegate('th.oe-record-selector', 'click', function (e) {
- e.stopPropagation();
- var selection = self.get_selection();
- $(self).trigger(
- 'selected', [selection.ids, selection.records]);
- })
- .delegate('td.oe-record-delete button', 'click', function (e) {
- e.stopPropagation();
- var $row = $(e.target).closest('tr');
- $(self).trigger('deleted', [[self.row_id($row)]]);
- })
- .delegate('td.oe-field-cell button', 'click', function (e) {
- e.stopPropagation();
- var $target = $(e.currentTarget),
- field = $target.closest('td').data('field'),
- $row = $target.closest('tr'),
- record_id = self.row_id($row);
-
- $(self).trigger('action', [field, record_id, function () {
- return self.reload_record(self.records.get(record_id));
- }]);
- })
- .delegate('tr', 'click', function (e) {
- e.stopPropagation();
- self.dataset.index = self.records.indexOf(
- self.records.get(
- self.row_id(e.currentTarget)));
- self.row_clicked(e);
- });
- },
- row_clicked: function () {
- $(this).trigger(
- 'row_link',
- [this.records.at(this.dataset.index).get('id'),
- this.dataset]);
- },
- render: function () {
- if (this.$current) {
- this.$current.remove();
- }
- this.$current = this.$_element.clone(true);
- this.$current.empty().append(
- QWeb.render('ListView.rows', _.extend({
- render_cell: openerp.base.format_cell}, this)));
- },
- /**
- * Gets the ids of all currently selected records, if any
- * @returns {Object} object with the keys ``ids`` and ``records``, holding respectively the ids of all selected records and the records themselves.
- */
- get_selection: function () {
- if (!this.options.selectable) {
- return [];
- }
- var records = this.records;
- var result = {ids: [], records: []};
- this.$current.find('th.oe-record-selector input:checked')
- .closest('tr').each(function () {
- var record = records.get($(this).data('id'));
- result.ids.push(record.get('id'));
- result.records.push(record.attributes);
- });
- return result;
- },
- /**
- * Returns the identifier of the object displayed in the provided table
- * row
- *
- * @param {Object} row the selected table row
- * @returns {Number|String} the identifier of the row's object
- */
- row_id: function (row) {
- return $(row).data('id');
- },
- /**
- * Death signal, cleans up list display
- */
- on_records_reset: function () {
- _(this.record_callbacks).each(function (callback, event) {
- this.records.unbind(event, callback);
- }, this);
- if (!this.$current) { return; }
- this.$current.remove();
- this.$current = null;
- this.$_element.remove();
- },
- get_records: function () {
- return this.records.map(function (record) {
- return {count: 1, values: record.attributes};
- });
- },
- /**
- * Reloads the provided record by re-reading its content from the server.
- *
- * @param {Record} record
- * @returns {$.Deferred} promise to the finalization of the reloading
- */
- reload_record: function (record) {
- return this.dataset.read_ids(
- [record.get('id')],
- _.pluck(_(this.columns).filter(function (r) {
- return r.tag === 'field';
- }), 'name'),
- function (records) {
- _(records[0]).each(function (value, key) {
- record.set(key, value, {silent: true});
- });
- record.trigger('change', record);
- }
- );
- },
- /**
- * Renders a list record to HTML
- *
- * @param {Record} record index of the record to render in ``this.rows``
- * @returns {String} QWeb rendering of the selected record
- */
- render_record: function (record) {
- var index = this.records.indexOf(record);
- return QWeb.render('ListView.row', {
- columns: this.columns,
- options: this.options,
- record: record,
- row_parity: (index % 2 === 0) ? 'even' : 'odd',
- render_cell: openerp.base.format_cell
- });
- },
- /**
- * Fixes fixes the even/odd classes
- *
- * @param {Number} [from_index] index from which to resequence
- * @param {Number} [offset = 0] selection offset for DOM, in case there are rows to ignore in the table
- */
- refresh_zebra: function (from_index, offset) {
- offset = offset || 0;
- from_index = from_index || 0;
- var dom_offset = offset + from_index;
- var sel = dom_offset ? ':gt(' + (dom_offset - 1) + ')' : null;
- this.$current.children(sel).each(function (i, e) {
- var index = from_index + i;
- // reset record-index accelerators on rows and even/odd
- var even = index%2 === 0;
- $(e).toggleClass('even', even)
- .toggleClass('odd', !even);
- });
- }
-});
-openerp.base.ListView.Groups = openerp.base.Class.extend( /** @lends openerp.base.ListView.Groups# */{
- passtrough_events: 'action deleted row_link',
- /**
- * Grouped display for the ListView. Handles basic DOM events and interacts
- * with the :js:class:`~openerp.base.DataGroup` bound to it.
- *
- * Provides events similar to those of
- * :js:class:`~openerp.base.ListView.List`
- *
- * @constructs
- * @param {openerp.base.ListView} view
- * @param {Object} [options]
- * @param {Collection} [options.records]
- * @param {Object} [options.options]
- * @param {Array} [options.columns]
- */
- init: function (view, options) {
- options = options || {};
- this.view = view;
- this.records = options.records || view.records;
- this.options = options.options || view.options;
- this.columns = options.columns || view.columns;
- this.datagroup = null;
-
- this.$row = null;
- this.children = {};
-
- this.page = 0;
-
- this.records.bind('reset', $.proxy(this, 'on_records_reset'));
- },
- make_fragment: function () {
- return document.createDocumentFragment();
- },
- /**
- * Returns a DOM node after which a new tbody can be inserted, so that it
- * follows the provided row.
- *
- * Necessary to insert the result of a new group or list view within an
- * existing groups render, without losing track of the groups's own
- * elements
- *
- * @param {HTMLTableRowElement} row the row after which the caller wants to insert a body
- * @returns {HTMLTableSectionElement} element after which a tbody can be inserted
- */
- point_insertion: function (row) {
- var $row = $(row);
- var red_letter_tboday = $row.closest('tbody')[0];
-
- var $next_siblings = $row.nextAll();
- if ($next_siblings.length) {
- var $root_kanal = $('<tbody>').insertAfter(red_letter_tboday);
-
- $root_kanal.append($next_siblings);
- this.elements.splice(
- _.indexOf(this.elements, red_letter_tboday),
- 0,
- $root_kanal[0]);
- }
- return red_letter_tboday;
- },
- make_paginator: function () {
- var self = this;
- var $prev = $('<button type="button" data-pager-action="previous">&lt;</button>')
- .click(function (e) {
- e.stopPropagation();
- self.page -= 1;
-
- self.$row.closest('tbody').next()
- .replaceWith(self.render());
- });
- var $next = $('<button type="button" data-pager-action="next">&gt;</button>')
- .click(function (e) {
- e.stopPropagation();
- self.page += 1;
-
- self.$row.closest('tbody').next()
- .replaceWith(self.render());
- });
- this.$row.children().last()
- .append($prev)
- .append('<span class="oe-pager-state"></span>')
- .append($next);
- },
- open: function (point_insertion) {
- this.render().insertAfter(point_insertion);
- this.make_paginator();
- },
- close: function () {
- this.$row.children().last().empty();
- this.records.reset();
- },
- /**
- * Prefixes ``$node`` with floated spaces in order to indent it relative
- * to its own left margin/baseline
- *
- * @param {jQuery} $node jQuery object to indent
- * @param {Number} level current nesting level, >= 1
- * @returns {jQuery} the indentation node created
- */
- indent: function ($node, level) {
- return $('<span>')
- .css({'float': 'left', 'white-space': 'pre'})
- .text(new Array(level).join(' '))
- .prependTo($node);
- },
- render_groups: function (datagroups) {
- var self = this;
- var placeholder = this.make_fragment();
- _(datagroups).each(function (group) {
- if (self.children[group.value]) {
- self.records.proxy(group.value).reset();
- delete self.children[group.value];
- }
- var child = self.children[group.value] = new openerp.base.ListView.Groups(self.view, {
- records: self.records.proxy(group.value),
- options: self.options,
- columns: self.columns
- });
- self.bind_child_events(child);
- child.datagroup = group;
-
- var $row = child.$row = $('<tr>');
- if (group.openable) {
- $row.click(function (e) {
- if (!$row.data('open')) {
- $row.data('open', true)
- .find('span.ui-icon')
- .removeClass('ui-icon-triangle-1-e')
- .addClass('ui-icon-triangle-1-s');
- child.open(self.point_insertion(e.currentTarget));
- } else {
- $row.removeData('open')
- .find('span.ui-icon')
- .removeClass('ui-icon-triangle-1-s')
- .addClass('ui-icon-triangle-1-e');
- child.close();
- }
- });
- }
- placeholder.appendChild($row[0]);
-
- var $group_column = $('<th class="oe-group-name">').appendTo($row);
- // Don't fill this if group_by_no_leaf but no group_by
- if (group.grouped_on) {
- var row_data = {};
- row_data[group.grouped_on] = group;
- var group_column = _(self.columns).detect(function (column) {
- return column.id === group.grouped_on; });
- $group_column.html(openerp.base.format_cell(
- row_data, group_column, "Undefined"
- ));
- if (group.openable) {
- // Make openable if not terminal group & group_by_no_leaf
- $group_column
- .prepend('<span class="ui-icon ui-icon-triangle-1-e" style="float: left;">');
- }
- }
- self.indent($group_column, group.level);
- // count column
- $('<td>').text(group.length).appendTo($row);
-
- if (self.options.selectable) {
- $row.append('<td>');
- }
- _(self.columns).chain()
- .filter(function (column) {return !column.invisible;})
- .each(function (column) {
- if (column.meta) {
- // do not do anything
- } else if (column.id in group.aggregates) {
- var value = group.aggregates[column.id];
- var format;
- if (column.type === 'integer') {
- format = "%.0f";
- } else if (column.type === 'float') {
- format = "%.2f";
- }
- $('<td>')
- .text(_.sprintf(format, value))
- .appendTo($row);
- } else {
- $row.append('<td>');
- }
- });
- if (self.options.deletable) {
- $row.append('<td class="oe-group-pagination">');
- }
- });
- return placeholder;
- },
- bind_child_events: function (child) {
- var $this = $(this),
- self = this;
- $(child).bind('selected', function (e) {
- // can have selections spanning multiple links
- var selection = self.get_selection();
- $this.trigger(e, [selection.ids, selection.records]);
- }).bind(this.passtrough_events, function (e) {
- // additional positional parameters are provided to trigger as an
- // Array, following the event type or event object, but are
- // provided to the .bind event handler as *args.
- // Convert our *args back into an Array in order to trigger them
- // on the group itself, so it can ultimately be forwarded wherever
- // it's supposed to go.
- var args = Array.prototype.slice.call(arguments, 1);
- $this.trigger.call($this, e, args);
- });
- },
- render_dataset: function (dataset) {
- var self = this,
- list = new openerp.base.ListView.List(this, {
- options: this.options,
- columns: this.columns,
- dataset: dataset,
- records: this.records
- });
- this.bind_child_events(list);
-
- var view = this.view,
- limit = view.limit(),
- d = new $.Deferred(),
- page = this.datagroup.openable ? this.page : view.page;
-
- var fields = _.pluck(_.select(this.columns, function(x) {return x.tag == "field"}), 'name');
- var options = { offset: page * limit, limit: limit };
- dataset.read_slice(fields, options , function (records) {
- if (!self.datagroup.openable) {
- view.configure_pager(dataset);
- } else {
- var pages = Math.ceil(dataset.ids.length / limit);
- self.$row
- .find('.oe-pager-state')
- .text(_.sprintf('%d/%d', page + 1, pages))
- .end()
- .find('button[data-pager-action=previous]')
- .attr('disabled', page === 0)
- .end()
- .find('button[data-pager-action=next]')
- .attr('disabled', page === pages - 1);
- }
-
- self.records.add(records, {silent: true});
- list.render();
- d.resolve(list);
- });
- return d.promise();
- },
- setup_resequence_rows: function (list, dataset) {
- // drag and drop enabled if list is not sorted and there is a
- // "sequence" column in the view.
- if ((dataset.sort && dataset.sort())
- || !_(this.columns).any(function (column) {
- return column.name === 'sequence'; })) {
- return;
- }
- // ondrop, move relevant record & fix sequences
- list.$current.sortable({
- stop: function (event, ui) {
- var to_move = list.records.get(ui.item.data('id')),
- target_id = ui.item.prev().data('id');
-
- list.records.remove(to_move);
- var to = target_id ? list.records.indexOf(list.records.get(target_id)) : 0;
- list.records.add(to_move, { at: to });
-
- // resequencing time!
- var record, index = to,
- // if drag to 1st row (to = 0), start sequencing from 0
- // (exclusive lower bound)
- seq = to ? list.records.at(to - 1).get('sequence') : 0;
- while (++seq, record = list.records.at(index++)) {
- // write are independent from one another, so we can just
- // launch them all at the same time and we don't really
- // give a fig about when they're done
- dataset.write(record.get('id'), {sequence: seq});
- record.set('sequence', seq);
- }
-
- list.refresh_zebra();
- }
- });
- },
- render: function (post_render) {
- var self = this;
- var $element = $('<tbody>');
- this.elements = [$element[0]];
-
- this.datagroup.list(
- _(this.view.visible_columns).chain()
- .filter(function (column) { return column.tag === 'field' })
- .pluck('name').value(),
- function (groups) {
- $element[0].appendChild(
- self.render_groups(groups));
- if (post_render) { post_render(); }
- }, function (dataset) {
- self.render_dataset(dataset).then(function (list) {
- self.children[null] = list;
- self.elements =
- [list.$current.replaceAll($element)[0]];
- self.setup_resequence_rows(list, dataset);
- if (post_render) { post_render(); }
- });
- });
- return $element;
- },
- /**
- * Returns the ids of all selected records for this group, and the records
- * themselves
- */
- get_selection: function () {
- var ids = [], records = [];
-
- _(this.children)
- .each(function (child) {
- var selection = child.get_selection();
- ids.push.apply(ids, selection.ids);
- records.push.apply(records, selection.records);
- });
-
- return {ids: ids, records: records};
- },
- on_records_reset: function () {
- this.children = {};
- $(this.elements).remove();
- },
- get_records: function () {
- if (_(this.children).isEmpty()) {
- return {
- count: this.datagroup.length,
- values: this.datagroup.aggregates
- }
- }
- return _(this.children).chain()
- .map(function (child) {
- return child.get_records();
- }).flatten().value();
- }
-});
-
-/**
- * @class
- * @extends openerp.base.Class
- */
-var Events = {
- /**
- * @param {String} event event to listen to on the current object, null for all events
- * @param {Function} handler event handler to bind to the relevant event
- * @returns this
- */
- bind: function (event, handler) {
- var calls = this['_callbacks'] || (this._callbacks = {});
-
- if (event in calls) {
- calls[event].push(handler);
- } else {
- calls[event] = [handler];
- }
- return this;
- },
- /**
- * @param {String} event event to unbind on the current object
- * @param {function} [handler] specific event handler to remove (otherwise unbind all handlers for the event)
- * @returns this
- */
- unbind: function (event, handler) {
- var calls = this._callbacks || {};
- if (!(event in calls)) { return this; }
- if (!handler) {
- delete calls[event];
- } else {
- var handlers = calls[event];
- handlers.splice(
- _(handlers).indexOf(handler),
- 1);
- }
- return this;
- },
- /**
- * @param {String} event
- * @returns this
- */
- trigger: function (event) {
- var calls;
- if (!(calls = this._callbacks)) { return this; }
- var callbacks = (calls[event] || []).concat(calls[null] || []);
- for(var i=0, length=callbacks.length; i<length; ++i) {
- callbacks[i].apply(this, arguments);
- }
- return this;
- }
-};
-var Record = openerp.base.Class.extend(/** @lends Record# */{
- /**
- * @constructs
- * @extends openerp.base.Class
- * @borrows Events#bind as this.bind
- * @borrows Events#trigger as this.trigger
- * @param {Object} [data]
- */
- init: function (data) {
- this.attributes = data || {};
- },
- /**
- * @param {String} key
- * @returns {Object}
- */
- get: function (key) {
- return this.attributes[key];
- },
- /**
- * @param key
- * @param value
- * @param {Object} [options]
- * @param {Boolean} [options.silent=false]
- * @returns {Record}
- */
- set: function (key, value, options) {
- options = options || {};
- var old_value = this.attributes[key];
- if (old_value === value) {
- return this;
- }
- this.attributes[key] = value;
- if (!options.silent) {
- this.trigger('change:' + key, this, value, old_value);
- this.trigger('change', this, key, value, old_value);
- }
- return this;
- },
- /**
- * Converts the current record to the format expected by form views:
- *
- * .. code-block:: javascript
- *
- * data: {
- * $fieldname: {
- * value: $value
- * }
- * }
- *
- *
- * @returns {Object} record displayable in a form view
- */
- toForm: function () {
- var form_data = {};
- _(this.attributes).each(function (value, key) {
- form_data[key] = {value: value};
- });
-
- return {data: form_data};
- }
-});
-Record.include(Events);
-var Collection = openerp.base.Class.extend(/** @lends Collection# */{
- /**
- * Smarter collections, with events, very strongly inspired by Backbone's.
- *
- * Using a "dumb" array of records makes synchronization between the
- * various serious
- *
- * @constructs
- * @extends openerp.base.Class
- * @borrows Events#bind as this.bind
- * @borrows Events#trigger as this.trigger
- * @param {Array} [records] records to initialize the collection with
- * @param {Object} [options]
- */
- init: function (records, options) {
- options = options || {};
- _.bindAll(this, '_onRecordEvent');
- this.length = 0;
- this.records = [];
- this._byId = {};
- this._proxies = {};
- this._key = options.key;
- this._parent = options.parent;
-
- if (records) {
- this.add(records);
- }
- },
- /**
- * @param {Object|Array} record
- * @param {Object} [options]
- * @param {Number} [options.at]
- * @param {Boolean} [options.silent=false]
- * @returns this
- */
- add: function (record, options) {
- options = options || {};
- var records = record instanceof Array ? record : [record];
-
- for(var i=0, length=records.length; i<length; ++i) {
- var instance = (records[i] instanceof Record) ? records[i] : new Record(records[i]);
- instance.bind(null, this._onRecordEvent);
- this._byId[instance.get('id')] = instance;
- if (options.at == undefined) {
- this.records.push(instance);
- if (!options.silent) {
- this.trigger('add', this, instance, this.records.length-1);
- }
- } else {
- var insertion_index = options.at + i;
- this.records.splice(insertion_index, 0, instance);
- if (!options.silent) {
- this.trigger('add', this, instance, insertion_index);
- }
- }
- this.length++;
- }
- return this;
- },
-
- /**
- * Get a record by its index in the collection, can also take a group if
- * the collection is not degenerate
- *
- * @param {Number} index
- * @param {String} [group]
- * @returns {Record|undefined}
- */
- at: function (index, group) {
- if (group) {
- var groups = group.split('.');
- return this._proxies[groups[0]].at(index, groups.join('.'));
- }
- return this.records[index];
- },
- /**
- * Get a record by its database id
- *
- * @param {Number} id
- * @returns {Record|undefined}
- */
- get: function (id) {
- if (!_(this._proxies).isEmpty()) {
- var record = null;
- _(this._proxies).detect(function (proxy) {
- return record = proxy.get(id);
- });
- return record;
- }
- return this._byId[id];
- },
- /**
- * Builds a proxy (insert/retrieve) to a subtree of the collection, by
- * the subtree's group
- *
- * @param {String} section group path section
- * @returns {Collection}
- */
- proxy: function (section) {
- return this._proxies[section] = new Collection(null, {
- parent: this,
- key: section
- }).bind(null, this._onRecordEvent);
- },
- /**
- * @param {Array} [records]
- * @returns this
- */
- reset: function (records) {
- _(this._proxies).each(function (proxy) {
- proxy.reset();
- });
- this._proxies = {};
- this.length = 0;
- this.records = [];
- this._byId = {};
- if (records) {
- this.add(records);
- }
- this.trigger('reset', this);
- return this;
- },
- /**
- * Removes the provided record from the collection
- *
- * @param {Record} record
- * @returns this
- */
- remove: function (record) {
- var self = this;
- var index = _(this.records).indexOf(record);
- if (index === -1) {
- _(this._proxies).each(function (proxy) {
- proxy.remove(record);
- });
- return this;
- }
-
- this.records.splice(index, 1);
- delete this._byId[record.get('id')];
- this.length--;
- this.trigger('remove', record, this);
- return this;
- },
-
- _onRecordEvent: function (event, record, options) {
- // don't propagate reset events
- if (event === 'reset') { return; }
- this.trigger.apply(this, arguments);
- },
-
- // underscore-type methods
- each: function (callback) {
- for(var section in this._proxies) {
- if (this._proxies.hasOwnProperty(section)) {
- this._proxies[section].each(callback);
- }
- }
- for(var i=0; i<this.length; ++i) {
- callback(this.records[i]);
- }
- },
- map: function (callback) {
- var results = [];
- this.each(function (record) {
- results.push(callback(record));
- });
- return results;
- },
- pluck: function (fieldname) {
- return this.map(function (record) {
- return record.get(fieldname);
- });
- },
- indexOf: function (record) {
- return _(this.records).indexOf(record);
- }
-});
-Collection.include(Events);
-openerp.base.list = {
- Events: Events,
- Record: Record,
- Collection: Collection
-}
-};
-// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
diff --git a/addons/base/static/src/js/search.js b/addons/base/static/src/js/search.js
deleted file mode 100644
index 94a8fa51aa0..00000000000
--- a/addons/base/static/src/js/search.js
+++ /dev/null
@@ -1,1177 +0,0 @@
-openerp.base.search = function(openerp) {
-
-openerp.base.SearchView = openerp.base.Widget.extend({
- init: function(parent, element_id, dataset, view_id, defaults) {
- this._super(parent, element_id);
- this.dataset = dataset;
- this.model = dataset.model;
- this.view_id = view_id;
-
- this.defaults = defaults || {};
-
- this.inputs = [];
- this.enabled_filters = [];
-
- this.has_focus = false;
-
- this.ready = $.Deferred();
- },
- start: function() {
- //this.log('Starting SearchView '+this.model+this.view_id)
- this.rpc("/base/searchview/load", {"model": this.model, "view_id":this.view_id}, this.on_loaded);
- return this.ready.promise();
- },
- show: function () {
- this.$element.show();
- },
- hide: function () {
- this.$element.hide();
- },
- /**
- * Builds a list of widget rows (each row is an array of widgets)
- *
- * @param {Array} items a list of nodes to convert to widgets
- * @param {Object} fields a mapping of field names to (ORM) field attributes
- * @returns Array
- */
- make_widgets: function (items, fields) {
- var rows = [],
- row = [];
- rows.push(row);
- var filters = [];
- _.each(items, function (item) {
- if (filters.length && item.tag !== 'filter') {
- row.push(
- new openerp.base.search.FilterGroup(
- filters, this));
- filters = [];
- }
-
- if (item.tag === 'newline') {
- row = [];
- rows.push(row);
- } else if (item.tag === 'filter') {
- if (!this.has_focus) {
- item.attrs.default_focus = '1';
- this.has_focus = true;
- }
- filters.push(
- new openerp.base.search.Filter(
- item, this));
- } else if (item.tag === 'separator') {
- // a separator is a no-op
- } else {
- if (item.tag === 'group') {
- // TODO: group and field should be fetched from registries, maybe even filters
- row.push(
- new openerp.base.search.Group(
- item, this, fields));
- } else if (item.tag === 'field') {
- if (!this.has_focus) {
- item.attrs.default_focus = '1';
- this.has_focus = true;
- }
- row.push(
- this.make_field(
- item, fields[item['attrs'].name]));
- }
- }
- }, this);
- if (filters.length) {
- row.push(new openerp.base.search.FilterGroup(filters, this));
- }
-
- return rows;
- },
- /**
- * Creates a field for the provided field descriptor item (which comes
- * from fields_view_get)
- *
- * @param {Object} item fields_view_get node for the field
- * @param {Object} field fields_get result for the field
- * @returns openerp.base.search.Field
- */
- make_field: function (item, field) {
- try {
- return new (openerp.base.search.fields.get_object(field.type))
- (item, field, this);
- } catch (e) {
- if (! e instanceof openerp.base.KeyNotFound) {
- throw e;
- }
- // KeyNotFound means unknown field type
- console.group('Unknown field type ' + field.type);
- console.error('View node', item);
- console.info('View field', field);
- console.info('In view', this);
- console.groupEnd();
- return null;
- }
- },
- on_loaded: function(data) {
- var self = this,
- lines = this.make_widgets(
- data.fields_view['arch'].children,
- data.fields_view.fields);
-
- // for extended search view
- var ext = new openerp.base.search.ExtendedSearch(this, this.model);
- lines.push([ext]);
- this.inputs.push(ext);
-
- var render = QWeb.render("SearchView", {
- 'view': data.fields_view['arch'],
- 'lines': lines,
- 'defaults': this.defaults
- });
-
- // We don't understand why the following commented line does not work in Chrome but
- // the non-commented line does. As far as we investigated, only God knows.
- //this.$element.html(render);
- jQuery(render).appendTo(this.$element);
- this.$element.find(".oe_search-view-custom-filter-btn").click(ext.on_activate);
-
- var f = this.$element.find('form');
- this.$element.find('form')
- .submit(this.do_search)
- .bind('reset', this.do_clear);
- // start() all the widgets
- var widget_starts = _(lines).chain().flatten().map(function (widget) {
- return widget.start();
- }).value();
-
- $.when.apply(null, widget_starts).then(function () {
- self.ready.resolve();
- });
-
- this.reload_managed_filters();
- },
- reload_managed_filters: function() {
- var self = this;
- return this.rpc('/base/searchview/get_filters', {
- model: this.dataset.model
- }).then(function(result) {
- self.managed_filters = result;
- var filters = self.$element.find(".oe_search-view-filters-management");
- filters.html(QWeb.render("SearchView.managed-filters", {filters: result}));
- filters.change(self.on_filters_management);
- });
- },
- /**
- * Handle event when the user make a selection in the filters management select box.
- */
- on_filters_management: function(e) {
- var self = this;
- var select = this.$element.find(".oe_search-view-filters-management");
- var val = select.val();
-
- if (val.slice(0,1) == "_") { // useless action
- select.val("_filters");
- return;
- }
- if (val.slice(0, "get:".length) == "get:") {
- val = val.slice("get:".length);
- val = parseInt(val);
- var filter = this.managed_filters[val];
- this.on_search([filter.domain], [filter.context], []);
- } else if (val == "save_filter") {
- select.val("_filters");
- var data = this.build_search_data();
- var context = new openerp.base.CompoundContext();
- _.each(data.contexts, function(x) {
- context.add(x);
- });
- var domain = new openerp.base.CompoundDomain();
- _.each(data.domains, function(x) {
- domain.add(x);
- });
- var dial_html = QWeb.render("SearchView.managed-filters.add");
- var $dial = $(dial_html);
- $dial.dialog({
- modal: true,
- title: "Filter Entry",
- buttons: {
- Cancel: function() {
- $(this).dialog("close");
- },
- OK: function() {
- $(this).dialog("close");
- var name = $(this).find("input").val();
- self.rpc('/base/searchview/save_filter', {
- model: self.dataset.model,
- context_to_save: context,
- domain: domain,
- name: name
- }).then(function() {
- self.reload_managed_filters();
- });
- }
- }
- });
- } else { // manage_filters
- select.val("_filters");
- this.do_action({
- res_model: 'ir.filters',
- views: [[false, 'list'], [false, 'form']],
- type: 'ir.actions.act_window',
- context: {"search_default_user_id": this.session.uid,
- "search_default_model_id": this.dataset.model},
- target: "current",
- limit : 80,
- auto_search : true
- });
- }
- },
- /**
- * Performs the search view collection of widget data.
- *
- * If the collection went well (all fields are valid), then triggers
- * :js:func:`openerp.base.SearchView.on_search`.
- *
- * If at least one field failed its validation, triggers
- * :js:func:`openerp.base.SearchView.on_invalid` instead.
- *
- * @param e jQuery event object coming from the "Search" button
- */
- do_search: function (e) {
- // reset filters management
- var select = this.$element.find(".oe_search-view-filters-management");
- select.val("_filters");
-
- if (e && e.preventDefault) { e.preventDefault(); }
-
- var data = this.build_search_data();
-
- if (data.errors.length) {
- this.on_invalid(data.errors);
- return;
- }
-
- this.on_search(data.domains, data.contexts, data.groupbys);
- },
- build_search_data: function() {
- var domains = [],
- contexts = [],
- errors = [];
-
- _.each(this.inputs, function (input) {
- try {
- var domain = input.get_domain();
- if (domain) {
- domains.push(domain);
- }
-
- var context = input.get_context();
- if (context) {
- contexts.push(context);
- }
- } catch (e) {
- if (e instanceof openerp.base.search.Invalid) {
- errors.push(e);
- } else {
- throw e;
- }
- }
- });
-
- // TODO: do we need to handle *fields* with group_by in their context?
- var groupbys = _(this.enabled_filters)
- .chain()
- .map(function (filter) { return filter.get_context();})
- .compact()
- .value();
- return {domains: domains, contexts: contexts, errors: errors, groupbys: groupbys};
- },
- /**
- * Triggered after the SearchView has collected all relevant domains and
- * contexts.
- *
- * It is provided with an Array of domains and an Array of contexts, which
- * may or may not be evaluated (each item can be either a valid domain or
- * context, or a string to evaluate in order in the sequence)
- *
- * It is also passed an array of contexts used for group_by (they are in
- * the correct order for group_by evaluation, which contexts may not be)
- *
- * @event
- * @param {Array} domains an array of literal domains or domain references
- * @param {Array} contexts an array of literal contexts or context refs
- * @param {Array} groupbys ordered contexts which may or may not have group_by keys
- */
- on_search: function (domains, contexts, groupbys) {
- },
- /**
- * Triggered after a validation error in the SearchView fields.
- *
- * Error objects have three keys:
- * * ``field`` is the name of the invalid field
- * * ``value`` is the invalid value
- * * ``message`` is the (in)validation message provided by the field
- *
- * @event
- * @param {Array} errors a never-empty array of error objects
- */
- on_invalid: function (errors) {
- this.notification.notify("Invalid Search", "triggered from search view");
- },
- do_clear: function () {
- $('.filter_label').removeClass('enabled');
- var string = $('a.searchview_group_string');
- _.each(string, function(str){
- $(str).closest('div.searchview_group').removeClass("expanded").addClass('folded');
- });
- this.$element.find('table:last').hide();
-
- $('.searchview_extended_groups_list').empty();
- setTimeout(this.on_clear);
- },
- /**
- * Triggered when the search view gets cleared
- *
- * @event
- */
- on_clear: function () {
- this.do_search();
- },
- /**
- * Called by a filter propagating its state changes
- *
- * @param {openerp.base.search.Filter} filter a filter which got toggled
- * @param {Boolean} default_enabled filter got enabled through the default values, at render time.
- */
- do_toggle_filter: function (filter, default_enabled) {
- if (default_enabled || filter.is_enabled()) {
- this.enabled_filters.push(filter);
- } else {
- this.enabled_filters = _.without(
- this.enabled_filters, filter);
- }
-
- if (!default_enabled) {
- // selecting a filter after initial loading automatically
- // triggers refresh
- this.$element.find('form').submit();
- }
- }
-});
-
-/** @namespace */
-openerp.base.search = {};
-/**
- * Registry of search fields, called by :js:class:`openerp.base.SearchView` to
- * find and instantiate its field widgets.
- */
-openerp.base.search.fields = new openerp.base.Registry({
- 'char': 'openerp.base.search.CharField',
- 'text': 'openerp.base.search.CharField',
- 'boolean': 'openerp.base.search.BooleanField',
- 'integer': 'openerp.base.search.IntegerField',
- 'float': 'openerp.base.search.FloatField',
- 'selection': 'openerp.base.search.SelectionField',
- 'datetime': 'openerp.base.search.DateTimeField',
- 'date': 'openerp.base.search.DateField',
- 'many2one': 'openerp.base.search.ManyToOneField',
- 'many2many': 'openerp.base.search.CharField',
- 'one2many': 'openerp.base.search.CharField'
-});
-openerp.base.search.Invalid = openerp.base.Class.extend( /** @lends openerp.base.search.Invalid# */{
- /**
- * Exception thrown by search widgets when they hold invalid values,
- * which they can not return when asked.
- *
- * @constructs
- * @param field the name of the field holding an invalid value
- * @param value the invalid value
- * @param message validation failure message
- */
- init: function (field, value, message) {
- this.field = field;
- this.value = value;
- this.message = message;
- },
- toString: function () {
- return ('Incorrect value for field ' + this.field +
- ': [' + this.value + '] is ' + this.message);
- }
-});
-openerp.base.search.Widget = openerp.base.Widget.extend( /** @lends openerp.base.search.Widget# */{
- template: null,
- /**
- * Root class of all search widgets
- *
- * @constructs
- * @extends openerp.base.Widget
- *
- * @param view the ancestor view of this widget
- */
- init: function (view) {
- this.view = view;
- },
- /**
- * Sets and returns a globally unique identifier for the widget.
- *
- * If a prefix is specified, the identifier will be appended to it.
- *
- * @params prefix prefix sections, empty/falsy sections will be removed
- */
- make_id: function () {
- this.element_id = _.uniqueId(
- ['search'].concat(
- _.compact(_.toArray(arguments)),
- ['']).join('_'));
- return this.element_id;
- },
- /**
- * "Starts" the widgets. Called at the end of the rendering, this allows
- * widgets to hook themselves to their view sections.
- *
- * On widgets, if they kept a reference to a view and have an element_id,
- * will fetch and set their root element on $element.
- */
- start: function () {
- this._super();
- if (this.view && this.element_id) {
- // id is unique, and no getElementById on elements
- this.$element = $(document.getElementById(
- this.element_id));
- }
- },
- /**
- * "Stops" the widgets. Called when the view destroys itself, this
- * lets the widgets clean up after themselves.
- */
- stop: function () {
- delete this.view;
- this._super();
- },
- render: function (defaults) {
- return QWeb.render(
- this.template, _.extend(this, {
- defaults: defaults
- }));
- }
-});
-openerp.base.search.FilterGroup = openerp.base.search.Widget.extend({
- template: 'SearchView.filters',
- init: function (filters, view) {
- this._super(view);
- this.filters = filters;
- this.length = filters.length;
- },
- start: function () {
- this._super();
- _.each(this.filters, function (filter) {
- filter.start();
- });
- }
-});
-openerp.base.search.add_expand_listener = function($root) {
- $root.find('a.searchview_group_string').click(function (e) {
- $root.toggleClass('folded expanded');
- e.stopPropagation();
- e.preventDefault();
- });
-};
-openerp.base.search.Group = openerp.base.search.Widget.extend({
- template: 'SearchView.group',
- init: function (view_section, view, fields) {
- this._super(view);
- this.attrs = view_section.attrs;
- this.lines = view.make_widgets(
- view_section.children, fields);
- this.make_id('group');
- },
- start: function () {
- this._super();
- openerp.base.search.add_expand_listener(this.$element);
- var widget_starts = _(this.lines).chain().flatten()
- .map(function (widget) { return widget.start(); })
- .value();
- return $.when.apply(null, widget_starts);
- }
-});
-
-openerp.base.search.Input = openerp.base.search.Widget.extend( /** @lends openerp.base.search.Input# */{
- /**
- * @constructs
- * @extends openerp.base.search.Widget
- *
- * @param view
- */
- init: function (view) {
- this._super(view);
- this.view.inputs.push(this);
- },
- get_context: function () {
- throw new Error(
- "get_context not implemented for widget " + this.attrs.type);
- },
- get_domain: function () {
- throw new Error(
- "get_domain not implemented for widget " + this.attrs.type);
- }
-});
-openerp.base.search.Filter = openerp.base.search.Input.extend({
- template: 'SearchView.filter',
- init: function (node, view) {
- this._super(view);
- this.attrs = node.attrs;
- this.classes = [this.attrs.string ? 'filter_label' : 'filter_icon'];
- this.make_id('filter', this.attrs.name);
- },
- start: function () {
- this._super();
- var self = this;
- this.$element.click(function (e) {
- $(this).toggleClass('enabled');
- self.view.do_toggle_filter(self);
- });
- },
- /**
- * Returns whether the filter is currently enabled (in use) or not.
- *
- * @returns a boolean
- */
- is_enabled:function () {
- return this.$element.hasClass('enabled');
- },
- /**
- * If the filter is present in the defaults (and has a truthy value),
- * enable the filter.
- *
- * @param {Object} defaults the search view's default values
- */
- render: function (defaults) {
- if (this.attrs.name && defaults[this.attrs.name]) {
- this.classes.push('enabled');
- this.view.do_toggle_filter(this, true);
- }
- return this._super(defaults);
- },
- get_context: function () {
- if (!this.is_enabled()) {
- return;
- }
- return this.attrs.context;
- },
- get_domain: function () {
- if (!this.is_enabled()) {
- return;
- }
- return this.attrs.domain;
- }
-});
-openerp.base.search.Field = openerp.base.search.Input.extend( /** @lends openerp.base.search.Field# */ {
- template: 'SearchView.field',
- default_operator: '=',
- /**
- * @constructs
- * @extends openerp.base.search.Input
- *
- * @param view_section
- * @param field
- * @param view
- */
- init: function (view_section, field, view) {
- this._super(view);
- this.attrs = _.extend({}, field, view_section.attrs);
- this.filters = new openerp.base.search.FilterGroup(_.map(
- view_section.children, function (filter_node) {
- return new openerp.base.search.Filter(
- filter_node, view);
- }), view);
- this.make_id('input', field.type, this.attrs.name);
- },
- start: function () {
- this._super();
- this.filters.start();
- },
- get_context: function () {
- var val = this.get_value();
- // A field needs a value to be "active", and a context to send when
- // active
- var has_value = (val !== null && val !== '');
- var context = this.attrs.context;
- if (!(has_value && context)) {
- return;
- }
- return _.extend(
- {}, context,
- {own_values: {self: val}});
- },
- /**
- * Function creating the returned domain for the field, override this
- * methods in children if you only need to customize the field's domain
- * without more complex alterations or tests (and without the need to
- * change override the handling of filter_domain)
- *
- * @param {String} name the field's name
- * @param {String} operator the field's operator (either attribute-specified or default operator for the field
- * @param {Number|String} value parsed value for the field
- * @returns {Array<Array>} domain to include in the resulting search
- */
- make_domain: function (name, operator, value) {
- return [[name, operator, value]];
- },
- get_domain: function () {
- var val = this.get_value();
- if (val === null || val === '') {
- return;
- }
-
- var domain = this.attrs['filter_domain'];
- if (!domain) {
- return this.make_domain(
- this.attrs.name,
- this.attrs.operator || this.default_operator,
- val);
- }
- return _.extend({}, domain, {own_values: {self: val}});
- }
-});
-/**
- * Implementation of the ``char`` OpenERP field type:
- *
- * * Default operator is ``ilike`` rather than ``=``
- *
- * * The Javascript and the HTML values are identical (strings)
- *
- * @class
- * @extends openerp.base.search.Field
- */
-openerp.base.search.CharField = openerp.base.search.Field.extend( /** @lends openerp.base.search.CharField# */ {
- default_operator: 'ilike',
- get_value: function () {
- return this.$element.val();
- }
-});
-openerp.base.search.NumberField = openerp.base.search.Field.extend(/** @lends openerp.base.search.NumberField# */{
- get_value: function () {
- if (!this.$element.val()) {
- return null;
- }
- var val = this.parse(this.$element.val()),
- check = Number(this.$element.val());
- if (isNaN(val) || val !== check) {
- this.$element.addClass('error');
- throw new openerp.base.search.Invalid(
- this.attrs.name, this.$element.val(), this.error_message);
- }
- this.$element.removeClass('error');
- return val;
- }
-});
-/**
- * @class
- * @extends openerp.base.search.NumberField
- */
-openerp.base.search.IntegerField = openerp.base.search.NumberField.extend(/** @lends openerp.base.search.IntegerField# */{
- error_message: "not a valid integer",
- parse: function (value) {
- return parseInt(value, 10);
- }
-});
-/**
- * @class
- * @extends openerp.base.search.NumberField
- */
-openerp.base.search.FloatField = openerp.base.search.NumberField.extend(/** @lends openerp.base.search.FloatField# */{
- error_message: "not a valid number",
- parse: function (value) {
- return parseFloat(value);
- }
-});
-/**
- * @class
- * @extends openerp.base.search.Field
- */
-openerp.base.search.SelectionField = openerp.base.search.Field.extend(/** @lends openerp.base.search.SelectionField# */{
- template: 'SearchView.field.selection',
- get_value: function () {
- return this.$element.val();
- }
-});
-openerp.base.search.BooleanField = openerp.base.search.SelectionField.extend(/** @lends openerp.base.search.BooleanField# */{
- /**
- * @constructs
- * @extends openerp.base.search.BooleanField
- */
- init: function () {
- this._super.apply(this, arguments);
- this.attrs.selection = [
- ['true', 'Yes'],
- ['false', 'No']
- ];
- },
- /**
- * Search defaults likely to be boolean values (for a boolean field).
- *
- * In the HTML, we only want/get strings, and our strings here are ``true``
- * and ``false``, so ensure we use precisely those by truth-testing the
- * default value (iif there is one in the view's defaults).
- *
- * @param {Object} defaults default values for this search view
- * @returns {String} rendered boolean field
- */
- render: function (defaults) {
- var name = this.attrs.name;
- if (name in defaults) {
- defaults[name] = defaults[name] ? "true" : "false";
- }
- return this._super(defaults);
- },
- get_value: function () {
- switch (this.$element.val()) {
- case 'false': return false;
- case 'true': return true;
- default: return null;
- }
- }
-});
-openerp.base.search.DateField = openerp.base.search.Field.extend( /** @lends openerp.base.search.DateField# */{
- /**
- * enables date picker on the HTML widgets
- */
- start: function () {
- this._super();
- this.$element.addClass('field_date').datepicker({
- dateFormat: 'yy-mm-dd'
- });
- },
- stop: function () {
- this.$element.datepicker('destroy');
- },
- get_value: function () {
- return this.$element.val();
- }
-});
-/**
- * Implementation of the ``datetime`` openerp field type:
- *
- * * Uses the same widget as the ``date`` field type (a simple date)
- *
- * * Builds a slighly more complex, it's a datetime range (includes time)
- * spanning the whole day selected by the date widget
- *
- * @class
- * @extends openerp.base.DateField
- */
-openerp.base.search.DateTimeField = openerp.base.search.DateField.extend(/** @lends openerp.base.search.DateTimeField# */{
- make_domain: function (name, operator, value) {
- return ['&', [name, '>=', value + ' 00:00:00'],
- [name, '<=', value + ' 23:59:59']];
- }
-});
-openerp.base.search.ManyToOneField = openerp.base.search.CharField.extend({
- init: function (view_section, field, view) {
- this._super(view_section, field, view);
- var self = this;
- this.got_name = $.Deferred().then(function () {
- self.$element.val(self.name);
- });
- this.dataset = new openerp.base.DataSet(
- this.view, this.attrs['relation']);
- },
- start: function () {
- this._super();
- this.setup_autocomplete();
- var started = $.Deferred();
- this.got_name.then(function () { started.resolve();},
- function () { started.resolve(); });
- return started.promise();
- },
- setup_autocomplete: function () {
- var self = this;
- this.$element.autocomplete({
- source: function (req, resp) {
- self.dataset.name_search(
- req.term, self.attrs.domain, 'ilike', 8, function (data) {
- resp(_.map(data, function (result) {
- return {id: result[0], label: result[1]}
- }));
- });
- },
- select: function (event, ui) {
- self.id = ui.item.id;
- self.name = ui.item.label;
- },
- delay: 0
- })
- },
- on_name_get: function (name_get) {
- if (!name_get.length) {
- delete this.id;
- this.got_name.reject();
- return;
- }
- this.name = name_get[0][1];
- this.got_name.resolve();
- },
- render: function (defaults) {
- if (defaults[this.attrs.name]) {
- this.id = defaults[this.attrs.name];
- if (this.id instanceof Array)
- this.id = this.id[0];
- // TODO: maybe this should not be completely removed
- delete defaults[this.attrs.name];
- this.dataset.name_get([this.id], $.proxy(this, 'on_name_get'));
- } else {
- this.got_name.reject();
- }
- return this._super(defaults);
- },
- make_domain: function (name, operator, value) {
- if (this.id && this.name) {
- if (value === this.name) {
- return [[name, '=', this.id]];
- } else {
- delete this.id;
- delete this.name;
- }
- }
- return this._super(name, operator, value);
- }
-});
-
-openerp.base.search.ExtendedSearch = openerp.base.OldWidget.extend({
- template: 'SearchView.extended_search',
- identifier_prefix: 'extended-search',
- init: function (parent, model) {
- this._super(parent);
- this.model = model;
- },
- add_group: function() {
- var group = new openerp.base.search.ExtendedSearchGroup(this, this.fields);
- group.appendTo(this.$element.find('.searchview_extended_groups_list'));
- this.check_last_element();
- },
- start: function () {
- this._super();
- if (!this.$element) {
- return; // not a logical state but sometimes it happens
- }
- this.$element.closest("table.oe-searchview-render-line").css("display", "none");
- var self = this;
- this.rpc("/base/searchview/fields_get",
- {"model": this.model}, function(data) {
- self.fields = data.fields;
- openerp.base.search.add_expand_listener(self.$element);
- self.$element.find('.searchview_extended_add_group').click(function (e) {
- self.add_group();
- });
- });
- },
- get_context: function() {
- return null;
- },
- get_domain: function() {
- if (!this.$element) {
- return null; // not a logical state but sometimes it happens
- }
- if(this.$element.closest("table.oe-searchview-render-line").css("display") == "none") {
- return null;
- }
- return _.reduce(this.widget_children,
- function(mem, x) { return mem.concat(x.get_domain());}, []);
- },
- on_activate: function() {
- this.add_group();
- var table = this.$element.closest("table.oe-searchview-render-line");
- table.css("display", "");
- if(this.$element.hasClass("folded")) {
- this.$element.toggleClass("folded expanded");
- }
- },
- hide: function() {
- var table = this.$element.closest("table.oe-searchview-render-line");
- table.css("display", "none");
- if(this.$element.hasClass("expanded")) {
- this.$element.toggleClass("folded expanded");
- }
- },
- check_last_element: function() {
- _.each(this.widget_children, function(x) {x.set_last_group(false);});
- if (this.widget_children.length >= 1) {
- this.widget_children[this.widget_children.length - 1].set_last_group(true);
- }
- }
-});
-
-openerp.base.search.ExtendedSearchGroup = openerp.base.OldWidget.extend({
- template: 'SearchView.extended_search.group',
- identifier_prefix: 'extended-search-group',
- init: function (parent, fields) {
- this._super(parent);
- this.fields = fields;
- },
- add_prop: function() {
- var prop = new openerp.base.search.ExtendedSearchProposition(this, this.fields);
- var render = prop.render({'index': this.widget_children.length - 1});
- this.$element.find('.searchview_extended_propositions_list').append(render);
- prop.start();
- },
- start: function () {
- this._super();
- var _this = this;
- this.add_prop();
- this.$element.find('.searchview_extended_add_proposition').click(function () {
- _this.add_prop();
- });
- this.$element.find('.searchview_extended_delete_group').click(function () {
- _this.stop();
- });
- },
- get_domain: function() {
- var props = _(this.widget_children).chain().map(function(x) {
- return x.get_proposition();
- }).compact().value();
- var choice = this.$element.find(".searchview_extended_group_choice").val();
- var op = choice == "all" ? "&" : "|";
- return choice == "none" ? ['!'] : [].concat(
- _.map(_.range(_.max([0,props.length - 1])), function() { return op; }),
- props);
- },
- stop: function() {
- var parent = this.widget_parent;
- if (this.widget_parent.widget_children.length == 1)
- this.widget_parent.hide();
- this._super();
- parent.check_last_element();
- },
- set_last_group: function(is_last) {
- this.$element.toggleClass('last_group', is_last);
- }
-});
-
-openerp.base.search.ExtendedSearchProposition = openerp.base.OldWidget.extend({
- template: 'SearchView.extended_search.proposition',
- identifier_prefix: 'extended-search-proposition',
- init: function (parent, fields) {
- this._super(parent);
- this.fields = _(fields).chain()
- .map(function(val, key) { return _.extend({}, val, {'name': key}); })
- .sortBy(function(field) {return field.string;})
- .value();
- this.attrs = {_: _, fields: this.fields, selected: null};
- this.value = null;
- },
- start: function () {
- this._super();
- this.select_field(this.fields.length > 0 ? this.fields[0] : null);
- var _this = this;
- this.$element.find(".searchview_extended_prop_field").change(function() {
- _this.changed();
- });
- this.$element.find('.searchview_extended_delete_prop').click(function () {
- _this.stop();
- });
- },
- stop: function() {
- var parent;
- if (this.widget_parent.widget_children.length == 1)
- parent = this.widget_parent;
- this._super();
- if (parent)
- parent.stop();
- },
- changed: function() {
- var nval = this.$element.find(".searchview_extended_prop_field").val();
- if(this.attrs.selected == null || nval != this.attrs.selected.name) {
- this.select_field(_.detect(this.fields, function(x) {return x.name == nval;}));
- }
- },
- /**
- * Selects the provided field object
- *
- * @param field a field descriptor object (as returned by fields_get, augmented by the field name)
- */
- select_field: function(field) {
- var _this = this;
- if(this.attrs.selected != null) {
- this.value.stop();
- this.value = null;
- this.$element.find('.searchview_extended_prop_op').html('');
- }
- this.attrs.selected = field;
- if(field == null) {
- return;
- }
-
- var type = field.type;
- try {
- openerp.base.search.custom_filters.get_object(type);
- } catch (e) {
- if (! e instanceof openerp.base.KeyNotFound) {
- throw e;
- }
- type = "char";
- this.log('Unknow field type ' + e.key);
- }
- this.value = new (openerp.base.search.custom_filters.get_object(type))
- (this);
- if(this.value.set_field) {
- this.value.set_field(field);
- }
- _.each(this.value.operators, function(operator) {
- var option = jQuery('<option>', {value: operator.value})
- .text(operator.text)
- .appendTo(_this.$element.find('.searchview_extended_prop_op'));
- });
- this.$element.find('.searchview_extended_prop_value').html(
- this.value.render({}));
- this.value.start();
-
- },
- get_proposition: function() {
- if ( this.attrs.selected == null)
- return null;
- var field = this.attrs.selected.name;
- var op = this.$element.find('.searchview_extended_prop_op').val();
- var value = this.value.get_value();
- return [field, op, value];
- }
-});
-
-openerp.base.search.ExtendedSearchProposition.Char = openerp.base.OldWidget.extend({
- template: 'SearchView.extended_search.proposition.char',
- identifier_prefix: 'extended-search-proposition-char',
- operators: [
- {value: "ilike", text: "contains"},
- {value: "not ilike", text: "doesn't contain"},
- {value: "=", text: "is equal to"},
- {value: "!=", text: "is not equal to"},
- {value: ">", text: "greater than"},
- {value: "<", text: "less than"},
- {value: ">=", text: "greater or equal than"},
- {value: "<=", text: "less or equal than"}
- ],
- get_value: function() {
- return this.$element.val();
- }
-});
-openerp.base.search.ExtendedSearchProposition.DateTime = openerp.base.OldWidget.extend({
- template: 'SearchView.extended_search.proposition.datetime',
- identifier_prefix: 'extended-search-proposition-datetime',
- operators: [
- {value: "=", text: "is equal to"},
- {value: "!=", text: "is not equal to"},
- {value: ">", text: "greater than"},
- {value: "<", text: "less than"},
- {value: ">=", text: "greater or equal than"},
- {value: "<=", text: "less or equal than"}
- ],
- get_value: function() {
- return this.$element.val();
- },
- start: function() {
- this._super();
- this.$element.datetimepicker({
- dateFormat: 'yy-mm-dd',
- timeFormat: 'hh:mm:ss'
- });
- }
-});
-openerp.base.search.ExtendedSearchProposition.Date = openerp.base.OldWidget.extend({
- template: 'SearchView.extended_search.proposition.date',
- identifier_prefix: 'extended-search-proposition-date',
- operators: [
- {value: "=", text: "is equal to"},
- {value: "!=", text: "is not equal to"},
- {value: ">", text: "greater than"},
- {value: "<", text: "less than"},
- {value: ">=", text: "greater or equal than"},
- {value: "<=", text: "less or equal than"}
- ],
- get_value: function() {
- return this.$element.val();
- },
- start: function() {
- this._super();
- this.$element.datepicker({
- dateFormat: 'yy-mm-dd',
- timeFormat: 'hh:mm:ss'
- });
- }
-});
-openerp.base.search.ExtendedSearchProposition.Integer = openerp.base.OldWidget.extend({
- template: 'SearchView.extended_search.proposition.integer',
- identifier_prefix: 'extended-search-proposition-integer',
- operators: [
- {value: "=", text: "is equal to"},
- {value: "!=", text: "is not equal to"},
- {value: ">", text: "greater than"},
- {value: "<", text: "less than"},
- {value: ">=", text: "greater or equal than"},
- {value: "<=", text: "less or equal than"}
- ],
- get_value: function() {
- var value = parseFloat(this.$element.val());
- if(value != 0 && !value) {
- return "";
- }
- return Math.round(value);
- }
-});
-openerp.base.search.ExtendedSearchProposition.Float = openerp.base.OldWidget.extend({
- template: 'SearchView.extended_search.proposition.float',
- identifier_prefix: 'extended-search-proposition-float',
- operators: [
- {value: "=", text: "is equal to"},
- {value: "!=", text: "is not equal to"},
- {value: ">", text: "greater than"},
- {value: "<", text: "less than"},
- {value: ">=", text: "greater or equal than"},
- {value: "<=", text: "less or equal than"}
- ],
- get_value: function() {
- var value = parseFloat(this.$element.val());
- if(value != 0 && !value) {
- return "";
- }
- return value;
- }
-});
-openerp.base.search.ExtendedSearchProposition.Selection = openerp.base.OldWidget.extend({
- template: 'SearchView.extended_search.proposition.selection',
- identifier_prefix: 'extended-search-proposition-selection',
- operators: [
- {value: "=", text: "is"},
- {value: "!=", text: "is not"}
- ],
- set_field: function(field) {
- this.field = field;
- },
- get_value: function() {
- return this.$element.val();
- }
-});
-openerp.base.search.ExtendedSearchProposition.Boolean = openerp.base.OldWidget.extend({
- template: 'SearchView.extended_search.proposition.boolean',
- identifier_prefix: 'extended-search-proposition-boolean',
- operators: [
- {value: "=", text: "is true"},
- {value: "!=", text: "is false"}
- ],
- get_value: function() {
- return true;
- }
-});
-
-openerp.base.search.custom_filters = new openerp.base.Registry({
- 'char': 'openerp.base.search.ExtendedSearchProposition.Char',
- 'text': 'openerp.base.search.ExtendedSearchProposition.Char',
- 'one2many': 'openerp.base.search.ExtendedSearchProposition.Char',
- 'many2one': 'openerp.base.search.ExtendedSearchProposition.Char',
- 'many2many': 'openerp.base.search.ExtendedSearchProposition.Char',
-
- 'datetime': 'openerp.base.search.ExtendedSearchProposition.DateTime',
- 'date': 'openerp.base.search.ExtendedSearchProposition.Date',
- 'integer': 'openerp.base.search.ExtendedSearchProposition.Integer',
- 'float': 'openerp.base.search.ExtendedSearchProposition.Float',
- 'boolean': 'openerp.base.search.ExtendedSearchProposition.Boolean',
- 'selection': 'openerp.base.search.ExtendedSearchProposition.Selection'
-});
-
-};
-
-// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
diff --git a/addons/base/static/src/js/view_editor.js b/addons/base/static/src/js/view_editor.js
deleted file mode 100644
index 753f9ac6d4e..00000000000
--- a/addons/base/static/src/js/view_editor.js
+++ /dev/null
@@ -1,147 +0,0 @@
-openerp.base.view_editor = function(openerp) {
-openerp.base.ViewEditor = openerp.base.Widget.extend({
- init: function(parent, element_id, dataset, view, options) {
- this._super(parent);
- this.element_id = element_id
- this.parent = parent
- this.dataset = dataset;
- this.model = dataset.model;
- this.xml_id = 0;
- },
- start: function() {
- this.View_editor();
- },
- View_editor : function(){
- var self = this;
- var action = {
- name:'ViewEditor',
- context:this.session.user_context,
- domain: [["model", "=", this.dataset.model]],
- res_model: 'ir.ui.view',
- views : [[false, 'list']],
- type: 'ir.actions.act_window',
- target: "current",
- limit : 80,
- auto_search : true,
- flags: {
- sidebar: false,
- views_switcher: false,
- action_buttons:false,
- search_view:false,
- pager:false,
- radio:true
- },
- };
- var action_manager = new openerp.base.ActionManager(this);
- this.dialog = new openerp.base.Dialog(this,{
- modal: true,
- title: 'ViewEditor',
- width: 750,
- height: 500,
- buttons: {
- "Create": function(){
-
- },
- "Edit": function(){
- self.xml_id=0;
- self.edit_view();
- },
- "Close": function(){
- $(this).dialog('destroy');
- }
- },
-
- });
- this.dialog.start();
- this.dialog.open();
- action_manager.appendTo(this.dialog);
- action_manager.do_action(action);
-
-
- },
- check_attr:function(xml,tag){
- var obj = new Object();
- obj.child_id = [];
- obj.id = this.xml_id++;
- var att_list = [];
- var name1 = "<" + tag;
- $(xml).each(function() {
- att_list = this.attributes;
- att_list = _.select(att_list, function(attrs){
- if(attrs.nodeName == "string" || attrs.nodeName == "name" || attrs.nodeName == "index"){
- name1 += ' ' +attrs.nodeName+'='+'"'+attrs.nodeValue+'"';}
- });
- name1+= ">";
- });
- obj.name = name1;
- return obj;
- },
- recursiveFunction : function(main_object,parent_id,child_id){
- var self = this;
- var check = false;
- var main_object = _.detect(main_object , function(node){
- if(node.id == parent_id){
- node.child_id = child_id;
- check = true;
- }
- return main_object;
- });
- if(check){
- return main_object;
- }else{
- //todo recursion for saving object into objects
- }
- },
- children_function : function(xml,root,main_object,parent_id){
- var self = this;
- var child_obj_list = [];
- var main_object = main_object;
- var children_list = $(xml).filter(root).children();
- _.each(children_list, function(child_node){
- var string = self.check_attr(child_node,child_node.tagName.toLowerCase());
- child_obj_list.push(string);
- });
- if(children_list.length != 0){
- main_object = self.recursiveFunction(main_object,parent_id,child_obj_list);
- }
- for(var i=0;i<children_list.length;i++){
- self.children_function(children_list[i],children_list[i].tagName.toLowerCase(),main_object,child_obj_list[i].id);
- }
- return child_obj_list;
- },
- edit_view : function(){
- var self = this;
- var view_id =(($("input[name='radiogroup']:checked").parent()).parent()).attr('data-id');
- var ve_dataset = new openerp.base.DataSet(this,'ir.ui.view');
- ve_dataset.read_ids([parseInt(view_id)],['arch'],function (arch) {
- var arch = arch[0].arch;
- var root = $(arch).filter(":first")[0];
- var tag = root.tagName.toLowerCase();
- var root_object = self.check_attr(root,tag);
- var all_list = self.children_function(arch,tag,[root_object],root_object.id);
-
- //todo render the final object of tree view so xml with it child node display...
- });
- this.dialog = new openerp.base.Dialog(this,{
- modal: true,
- title: 'Edit Xml',
- width: 750,
- height: 500,
- buttons: {
- "Inherited View": function(){
-
- },
- "Preview": function(){
-
- },
- "Close": function(){
- $(this).dialog('destroy');
- }
- },
-
- });
- this.dialog.start().open();
- }
-
-});
-};
diff --git a/addons/base/static/src/js/view_help.js b/addons/base/static/src/js/view_help.js
deleted file mode 100644
index aa98f59c3ab..00000000000
--- a/addons/base/static/src/js/view_help.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/*---------------------------------------------------------
- * OpenERP base library
- *---------------------------------------------------------*/
-
-openerp.base.view_help = function(openerp) {
-
-openerp.base.ProcessView = openerp.base.Widget.extend({
-});
-
-openerp.base.HelpView = openerp.base.Widget.extend({
-});
-
-};
-
-// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
diff --git a/addons/base/static/src/js/view_tree.js b/addons/base/static/src/js/view_tree.js
deleted file mode 100644
index 59544a998b3..00000000000
--- a/addons/base/static/src/js/view_tree.js
+++ /dev/null
@@ -1,206 +0,0 @@
-/*---------------------------------------------------------
- * OpenERP base library
- *---------------------------------------------------------*/
-
-openerp.base.view_tree = function(openerp) {
-
-openerp.base.views.add('tree', 'openerp.base.TreeView');
-/**
- * Genuine tree view (the one displayed as a tree, not the list)
- */
-openerp.base.TreeView = openerp.base.View.extend({
- /**
- * Indicates that this view is not searchable, and thus that no search
- * view should be displayed (if there is one active).
- */
- searchable : false,
-
- init: function(parent, element_id, dataset, view_id, options) {
- this._super(parent, element_id);
- this.dataset = dataset;
- this.model = dataset.model;
- this.view_id = view_id;
-
- this.records = {};
-
- this.options = _.extend({}, this.defaults, options || {});
- },
-
- start: function () {
- this._super();
- return this.rpc("/base/treeview/load", {
- model: this.model,
- view_id: this.view_id,
- toolbar: this.view_manager ? !!this.view_manager.sidebar : false
- }, this.on_loaded);
- },
- /**
- * Returns the list of fields needed to correctly read objects.
- *
- * Gathers the names of all fields in fields_view_get, and adds the
- * field_parent (children_field in the tree view) if it's not already one
- * of the fields to fetch
- *
- * @returns {Array} an array of fields which can be provided to DataSet.read_slice and others
- */
- fields_list: function () {
- var fields = _.keys(this.fields);
- if (!_(fields).contains(this.children_field)) {
- fields.push(this.children_field);
- }
- return fields;
- },
- on_loaded: function (fields_view) {
- var self = this;
- var has_toolbar = !!fields_view.arch.attrs.toolbar;
- // field name in OpenERP is kinda stupid: this is the name of the field
- // holding the ids to the children of the current node, why call it
- // field_parent?
- this.children_field = fields_view['field_parent'];
- this.fields_view = fields_view;
- _(this.fields_view.arch.children).each(function (field) {
- if (field.attrs.modifiers) {
- field.attrs.modifiers = JSON.parse(field.attrs.modifiers);
- }
- });
- this.fields = fields_view.fields;
- this.hook_row_click();
- this.$element.html(QWeb.render('TreeView', {
- 'title': this.fields_view.arch.attrs.string,
- 'fields_view': this.fields_view.arch.children,
- 'fields': this.fields,
- 'toolbar': has_toolbar
- }));
-
- this.dataset.read_slice(this.fields_list(), {}, function (records) {
- if (!has_toolbar) {
- // WARNING: will do a second read on the same ids, but only on
- // first load so not very important
- self.getdata(null, _(records).pluck('id'));
- return;
- }
-
- var $select = self.$element.find('select')
- .change(function () {
- var $option = $(this).find(':selected');
- self.getdata($option.val(), $option.data('children'));
- });
- _(records).each(function (record) {
- self.records[record.id] = record;
- $('<option>')
- .val(record.id)
- .text(record.name)
- .data('children', record[self.children_field])
- .appendTo($select);
- });
-
- if (!_.isEmpty(records)) {
- $select.change();
- }
- });
- },
- /**
- * Sets up opening a row
- */
- hook_row_click: function () {
- var self = this;
- this.$element.delegate('.treeview-td span, .treeview-tr span', 'click', function (e) {
- e.stopImmediatePropagation();
- self.activate($(this).closest('tr').data('id'));
- });
-
- this.$element.delegate('.treeview-tr', 'click', function () {
- var is_loaded = 0,
- $this = $(this),
- record_id = $this.data('id'),
- record = self.records[record_id],
- children_ids = record[self.children_field];
-
- _(children_ids).each(function(childid) {
- if (self.$element.find('#treerow_' + childid).length) {
- if (self.$element.find('#treerow_' + childid).is(':hidden')) {
- is_loaded = -1;
- } else {
- is_loaded++;
- }
- }
- });
- if (is_loaded === 0) {
- if (!$this.parent().hasClass('oe-open')) {
- self.getdata(record_id, children_ids);
- }
- } else {
- self.showcontent(record_id, is_loaded < 0);
- }
- });
- },
- // get child data of selected value
- getdata: function (id, children_ids) {
- var self = this;
-
- self.dataset.read_ids(children_ids, this.fields_list(), function (records) {
- _(records).each(function (record) {
- self.records[record.id] = record;
- });
-
- var $curr_node = self.$element.find('#treerow_' + id);
- var children_rows = QWeb.render('TreeView.rows', {
- 'records': records,
- 'children_field': self.children_field,
- 'fields_view': self.fields_view.arch.children,
- 'fields': self.fields,
- 'level': $curr_node.data('level') || 0,
- 'render': openerp.base.format_value
- });
-
- if ($curr_node.length) {
- $curr_node.addClass('oe-open');
- $curr_node.after(children_rows);
- } else {
- self.$element.find('tbody').html(children_rows);
- }
- });
- },
-
- // Get details in listview
- activate: function(id) {
- var self = this;
- this.rpc('/base/treeview/action', {
- id: id,
- model: this.dataset.model,
- context: new openerp.base.CompoundContext(
- this.dataset.get_context(), {
- active_model: this.dataset.model,
- active_id: id,
- active_ids: [id]})
- }, function (actions) {
- if (!actions.length) { return; }
- var action = actions[0][2];
- self.do_action(action);
- });
- },
-
- // show & hide the contents
- showcontent: function (record_id, show) {
- this.$element.find('#treerow_' + record_id)
- .toggleClass('oe-open', show);
-
- _(this.records[record_id][this.children_field]).each(function (child_id) {
- var $child_row = this.$element.find('#treerow_' + child_id);
- if ($child_row.hasClass('oe-open')) {
- this.showcontent(child_id, false);
- }
- $child_row.toggle(show);
- }, this);
- },
-
- do_show: function () {
- this.$element.show();
- },
-
- do_hide: function () {
- this.$element.hide();
- this.hidden = true;
- }
-});
-};
diff --git a/addons/base/static/src/js/views.js b/addons/base/static/src/js/views.js
deleted file mode 100644
index 11b45cbfeb0..00000000000
--- a/addons/base/static/src/js/views.js
+++ /dev/null
@@ -1,791 +0,0 @@
-/*---------------------------------------------------------
- * OpenERP base library
- *---------------------------------------------------------*/
-
-openerp.base.views = function(openerp) {
-
-var _t = openerp.base._t;
-
-/**
- * Registry for all the client actions key: tag value: widget
- */
-openerp.base.client_actions = new openerp.base.Registry();
-
-openerp.base.ActionManager = openerp.base.Widget.extend({
- identifier_prefix: "actionmanager",
- init: function(parent) {
- this._super(parent);
- this.inner_viewmanager = null;
- this.dialog = null;
- this.dialog_viewmanager = null;
- this.client_widget = null;
- this.url = {}
- },
- render: function() {
- return "<div id='"+this.element_id+"'></div>";
- },
- dialog_stop: function () {
- if (this.dialog) {
- this.dialog_viewmanager.stop();
- this.dialog_viewmanager = null;
- this.dialog.stop();
- this.dialog = null;
- }
- },
- content_stop: function () {
- if (this.inner_viewmanager) {
- this.inner_viewmanager.stop();
- this.inner_viewmanager = null;
- }
- if (this.client_widget) {
- this.client_widget.stop();
- this.client_widget = null;
- }
- },
- url_update: function(action) {
- // this.url = {
- // "model": action.model,
- // "domain": action.domain,
- // };
- // action.res_model
- // action.domain
- // action.context
- // after
- // action.views
- // action.res_id
- // mode
- // menu
- },
- url_stringify: function(action) {
- },
- url_parse: function(action) {
- },
- on_url_update: function(url) {
- },
- do_url_action: function(url) {
- },
- do_action: function(action, on_close) {
- var type = action.type.replace(/\./g,'_');
- var popup = action.target === 'new';
- action.flags = _.extend({
- views_switcher : !popup,
- search_view : !popup,
- action_buttons : !popup,
- sidebar : !popup,
- pager : !popup
- }, action.flags || {});
- if (!(type in this)) {
- this.log("Action manager can't handle action of type " + action.type, action);
- return;
- }
- this[type](action, on_close);
- },
- ir_actions_act_window: function (action, on_close) {
- if (action.target === 'new') {
- if (this.dialog == null) {
- this.dialog = new openerp.base.Dialog(this, { title: action.name, width: '80%' });
- if(on_close)
- this.dialog.on_close.add(on_close);
- this.dialog.start();
- } else {
- this.dialog_viewmanager.stop();
- }
- this.dialog_viewmanager = new openerp.base.ViewManagerAction(this, action);
- this.dialog_viewmanager.appendTo(this.dialog.$element);
- this.dialog.open();
- } else {
- this.dialog_stop();
- this.content_stop();
- this.inner_viewmanager = new openerp.base.ViewManagerAction(this, action);
- this.inner_viewmanager.appendTo(this.$element);
- this.url_update(action);
- }
- /* new window code
- this.rpc("/base/session/save_session_action", { the_action : action}, function(key) {
- var url = window.location.protocol + "//" + window.location.host + window.location.pathname + "?" + jQuery.param({ s_action : "" + key });
- window.open(url,'_blank');
- });
- */
- },
- ir_actions_act_window_close: function (action, on_closed) {
- this.dialog_stop();
- },
- ir_actions_server: function (action, on_closed) {
- var self = this;
- this.rpc('/base/action/run', {
- action_id: action.id,
- context: {active_id: 66, active_ids: [66], active_model: 'ir.ui.menu'}
- }).then(function (action) {
- self.do_action(action, on_closed)
- });
- },
- ir_actions_client: function (action) {
- this.content_stop();
- var ClientWidget = openerp.base.client_actions.get_object(action.tag);
- (this.client_widget = new ClientWidget(this, action.params)).appendTo(this);
- },
- ir_actions_report_xml: function(action) {
- this.rpc('/base/report/get_report', {
- action: action,
- context: {}
- }).then(function(result) {
- debugger;
- });
- }
-});
-
-openerp.base.ViewManager = openerp.base.Widget.extend({
- identifier_prefix: "viewmanager",
- init: function(parent, dataset, views) {
- this._super(parent);
- this.model = dataset.model;
- this.dataset = dataset;
- this.searchview = null;
- this.active_view = null;
- this.views_src = _.map(views, function(x) {return x instanceof Array? {view_id: x[0], view_type: x[1]} : x;});
- this.views = {};
- this.flags = this.flags || {};
- this.registry = openerp.base.views;
- },
- render: function() {
- return QWeb.render("ViewManager", {"prefix": this.element_id, views: this.views_src})
- },
- /**
- * @returns {jQuery.Deferred} initial view loading promise
- */
- start: function() {
- this._super();
- var self = this;
- this.dataset.start();
- this.$element.find('.oe_vm_switch button').click(function() {
- self.on_mode_switch($(this).data('view-type'));
- });
- var views_ids = {};
- _.each(this.views_src, function(view) {
- self.views[view.view_type] = $.extend({}, view, {
- controller : null,
- options : _.extend({
- sidebar_id : self.element_id + '_sidebar_' + view.view_type,
- action : self.action,
- action_views_ids : views_ids
- }, self.flags, view.options || {})
- });
- views_ids[view.view_type] = view.view_id;
- });
- if (this.flags.views_switcher === false) {
- this.$element.find('.oe_vm_switch').hide();
- }
- // switch to the first one in sequence
- return this.on_mode_switch(this.views_src[0].view_type);
- },
- /**
- * Asks the view manager to switch visualization mode.
- *
- * @param {String} view_type type of view to display
- * @returns {jQuery.Deferred} new view loading promise
- */
- on_mode_switch: function(view_type) {
- var self = this,
- view_promise;
- this.active_view = view_type;
- var view = this.views[view_type];
- if (!view.controller) {
- // Lazy loading of views
- var controllerclass = this.registry.get_object(view_type);
- var controller = new controllerclass(this, this.element_id + '_view_' + view_type,
- this.dataset, view.view_id, view.options);
- if (view.embedded_view) {
- controller.set_embedded_view(view.embedded_view);
- }
- controller.do_switch_view.add_last(this.on_mode_switch);
- if (view_type === 'list' && this.flags.search_view === false && this.action && this.action['auto_search']) {
- // In case the search view is not instantiated: manually call ListView#search
- var domains = !_(self.action.domain).isEmpty()
- ? [self.action.domain] : [],
- contexts = !_(self.action.context).isEmpty()
- ? [self.action.context] : [];
- controller.on_loaded.add({
- callback: function () {
- controller.do_search(domains, contexts, []);
- },
- position: 'last',
- unique: true
- });
- }
- view_promise = controller.start();
- $.when(view_promise).then(function() {
- self.on_controller_inited(view_type, controller);
- });
- this.views[view_type].controller = controller;
- }
-
-
- if (this.searchview) {
- if (view.controller.searchable === false) {
- this.searchview.hide();
- } else {
- this.searchview.show();
- }
- }
-
- this.$element
- .find('.views-switchers button').removeAttr('disabled')
- .filter('[data-view-type="' + view_type + '"]')
- .attr('disabled', true);
-
- for (var view_name in this.views) {
- if (!this.views.hasOwnProperty(view_name)) { continue; }
- if (this.views[view_name].controller) {
- if (view_name === view_type) {
- $.when(view_promise).then(this.views[view_name].controller.do_show);
- } else {
- this.views[view_name].controller.do_hide();
- }
- }
- }
- return view_promise;
- },
- /**
- * Event launched when a controller has been inited.
- *
- * @param {String} view_type type of view
- * @param {String} view the inited controller
- */
- on_controller_inited: function(view_type, view) {
- },
- /**
- * Sets up the current viewmanager's search view.
- *
- * @param view_id the view to use or false for a default one
- * @returns {jQuery.Deferred} search view startup deferred
- */
- setup_search_view: function(view_id, search_defaults) {
- var self = this;
- if (this.searchview) {
- this.searchview.stop();
- }
- this.searchview = new openerp.base.SearchView(this, this.element_id + "_search", this.dataset, view_id, search_defaults);
- if (this.flags.search_view === false) {
- this.searchview.hide();
- }
- this.searchview.on_search.add(function(domains, contexts, groupbys) {
- var controller = self.views[self.active_view].controller;
- controller.do_search.call(controller, domains, contexts, groupbys);
- });
- return this.searchview.start();
- },
- /**
- * Called when one of the view want to execute an action
- */
- on_action: function(action) {
- },
- on_create: function() {
- },
- on_remove: function() {
- },
- on_edit: function() {
- }
-});
-
-openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
- init: function(parent, action) {
- this.session = parent.session;
- this.action = action;
- var dataset;
- if (!action.res_id) {
- dataset = new openerp.base.DataSetSearch(this, action.res_model, action.context, action.domain);
- } else {
- this.action.flags.search_view = false;
- dataset = new openerp.base.DataSetStatic(this, action.res_model, action.context, [action.res_id]);
- dataset.index = 0;
- }
- this._super(parent, dataset, action.views);
- this.action = action;
- this.flags = this.action.flags || {};
- if (action.res_model == 'board.board' && action.views.length == 1 && action.views) {
- // Not elegant but allows to avoid flickering of SearchView#do_hide
- this.flags.search_view = this.flags.pager = this.flags.sidebar = this.flags.action_buttons = false;
- }
- },
- start: function() {
- var inital_view_loaded = this._super();
-
- var search_defaults = {};
- _.each(this.action.context, function (value, key) {
- var match = /^search_default_(.*)$/.exec(key);
- if (match) {
- search_defaults[match[1]] = value;
- }
- });
-
- if (this.flags.search_view !== false) {
- // init search view
- var searchview_id = this.action.search_view_id && this.action.search_view_id[0];
-
- var searchview_loaded = this.setup_search_view(
- searchview_id || false, search_defaults);
-
- // schedule auto_search
- if (searchview_loaded != null && this.action['auto_search']) {
- $.when(searchview_loaded, inital_view_loaded)
- .then(this.searchview.do_search);
- }
- }
- },
- on_mode_switch: function (view_type) {
- return $.when(
- this._super(view_type),
- this.shortcut_check(this.views[view_type]));
- },
- shortcut_check : function(view) {
- var self = this;
- var grandparent = this.widget_parent && this.widget_parent.widget_parent;
- // display shortcuts if on the first view for the action
- var $shortcut_toggle = this.$element.find('.oe-shortcut-toggle');
- if (!(grandparent instanceof openerp.base.WebClient) ||
- !(view.view_type === this.views_src[0].view_type
- && view.view_id === this.views_src[0].view_id)) {
- $shortcut_toggle.hide();
- return;
- }
- $shortcut_toggle.removeClass('oe-shortcut-remove').show();
- if (_(this.session.shortcuts).detect(function (shortcut) {
- return shortcut.res_id === self.session.active_id; })) {
- $shortcut_toggle.addClass("oe-shortcut-remove");
- }
- this.shortcut_add_remove();
- },
- shortcut_add_remove: function() {
- var self = this;
- var $shortcut_toggle = this.$element.find('.oe-shortcut-toggle');
- $shortcut_toggle
- .unbind("click")
- .click(function() {
- if ($shortcut_toggle.hasClass("oe-shortcut-remove")) {
- $(self.session.shortcuts.binding).trigger('remove-current');
- $shortcut_toggle.removeClass("oe-shortcut-remove");
- } else {
- $(self.session.shortcuts.binding).trigger('add', {
- 'user_id': self.session.uid,
- 'res_id': self.session.active_id,
- 'resource': 'ir.ui.menu',
- 'name': self.action.name
- });
- $shortcut_toggle.addClass("oe-shortcut-remove");
- }
- });
- }
-});
-
-openerp.base.Sidebar = openerp.base.Widget.extend({
- init: function(parent, element_id) {
- this._super(parent, element_id);
- this.items = {};
- this.sections = {};
- },
- start: function() {
- this._super(this);
- var self = this;
- this.$element.html(QWeb.render('Sidebar'));
- this.$element.find(".toggle-sidebar").click(function(e) {
- self.do_toggle();
- });
- },
- add_toolbar: function(toolbar) {
- var self = this;
- _.each([['print', "Reports"], ['action', "Actions"], ['relate', "Links"]], function(type) {
- var items = toolbar[type[0]];
- if (items.length) {
- for (var i = 0; i < items.length; i++) {
- items[i] = {
- label: items[i]['name'],
- action: items[i],
- classname: 'oe_sidebar_' + type[0]
- }
- }
- self.add_section(type[0], type[1], items);
- }
- });
- },
- add_section: function(code, name, items) {
- // For each section, we pass a name/label and optionally an array of items.
- // If no items are passed, then the section will be created as a custom section
- // returning back an element_id to be used by a custom controller.
- // Else, the section is a standard section with items displayed as links.
- // An item is a dictonary : {
- // label: label to be displayed for the link,
- // action: action to be launch when the link is clicked,
- // callback: a function to be executed when the link is clicked,
- // classname: optional dom class name for the line,
- // title: optional title for the link
- // }
- // Note: The item should have one action or/and a callback
- var self = this,
- section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
- if (items) {
- for (var i = 0; i < items.length; i++) {
- items[i].element_id = _.uniqueId(section_id + '_item_');
- this.items[items[i].element_id] = items[i];
- }
- }
- var $section = $(QWeb.render("Sidebar.section", {
- section_id: section_id,
- name: name,
- classname: 'oe_sidebar_' + code,
- items: items
- }));
- if (items) {
- $section.find('a.oe_sidebar_action_a').click(function() {
- var item = self.items[$(this).attr('id')];
- if (item.callback) {
- item.callback();
- }
- if (item.action) {
- var ids = self.widget_parent.get_selected_ids();
- if (ids.length == 0) {
- //TODO niv: maybe show a warning?
- return false;
- }
- var additional_context = {
- active_id: ids[0],
- active_ids: ids,
- active_model: self.widget_parent.dataset.model
- };
- self.rpc("/base/action/load", {
- action_id: item.action.id,
- context: additional_context
- }, function(result) {
- result.result.context = _.extend(result.result.context || {},
- additional_context);
- result.result.flags = result.result.flags || {};
- result.result.flags.new_window = true;
- self.do_action(result.result);
- });
- }
- return false;
- });
- }
- $section.appendTo(this.$element.find('div.sidebar-actions'));
- this.sections[code] = $section;
- return section_id;
- },
- do_fold: function() {
- this.$element.addClass('closed-sidebar').removeClass('open-sidebar');
- },
- do_unfold: function() {
- this.$element.addClass('open-sidebar').removeClass('closed-sidebar');
- },
- do_toggle: function() {
- this.$element.toggleClass('open-sidebar closed-sidebar');
- }
-});
-
-openerp.base.TranslateDialog = openerp.base.Dialog.extend({
- dialog_title: _t("Translations"),
- init: function(view) {
- // TODO fme: should add the language to fields_view_get because between the fields view get
- // and the moment the user opens the translation dialog, the user language could have been changed
- this.view_language = view.session.user_context.lang;
- this['on_button' + _t("Save")] = this.on_button_Save;
- this['on_button' + _t("Close")] = this.on_button_Close;
- this._super(view, {
- width: '80%',
- height: '80%'
- });
- this.view = view;
- this.view_type = view.fields_view.type || '';
- this.$fields_form = null;
- this.$view_form = null;
- this.$sidebar_form = null;
- this.translatable_fields_keys = _.map(this.view.translatable_fields || [], function(i) { return i.name });
- this.languages = null;
- this.languages_loaded = $.Deferred();
- (new openerp.base.DataSetSearch(this, 'res.lang', this.view.dataset.get_context(),
- [['translatable', '=', '1']])).read_slice(['code', 'name'], { sort: 'id' }, this.on_languages_loaded);
- },
- start: function() {
- var self = this;
- this._super();
- $.when(this.languages_loaded).then(function() {
- self.$element.html(QWeb.render('TranslateDialog', { widget: self }));
- self.$element.tabs();
- if (!(self.view.translatable_fields && self.view.translatable_fields.length)) {
- self.hide_tabs('fields');
- self.select_tab('view');
- }
- self.$fields_form = self.$element.find('.oe_translation_form');
- self.$fields_form.find('.oe_trad_field').change(function() {
- $(this).toggleClass('touched', ($(this).val() != $(this).attr('data-value')));
- });
- });
- return this;
- },
- on_languages_loaded: function(langs) {
- this.languages = langs;
- this.languages_loaded.resolve();
- },
- do_load_fields_values: function(callback) {
- var self = this,
- deffered = [];
- this.$fields_form.find('.oe_trad_field').val('').removeClass('touched');
- _.each(self.languages, function(lg) {
- var deff = $.Deferred();
- deffered.push(deff);
- var callback = function(values) {
- _.each(self.translatable_fields_keys, function(f) {
- self.$fields_form.find('.oe_trad_field[name="' + lg.code + '-' + f + '"]').val(values[0][f] || '').attr('data-value', values[0][f] || '');
- });
- deff.resolve();
- }
- if (lg.code === self.view_language) {
- var values = {};
- _.each(self.translatable_fields_keys, function(field) {
- values[field] = self.view.fields[field].get_value();
- });
- callback([values]);
- } else {
- self.rpc('/base/dataset/get', {
- model: self.view.dataset.model,
- ids: [self.view.datarecord.id],
- fields: self.translatable_fields_keys,
- context: self.view.dataset.get_context({
- 'lang': lg.code
- })}, callback);
- }
- });
- $.when.apply(null, deffered).then(callback);
- },
- show_tabs: function() {
- for (var i = 0; i < arguments.length; i++) {
- this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().show();
- }
- },
- hide_tabs: function() {
- for (var i = 0; i < arguments.length; i++) {
- this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().hide();
- }
- },
- select_tab: function(name) {
- this.show_tabs(name);
- var index = this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().index() - 1;
- this.$element.tabs('select', index);
- },
- open: function(field) {
- var self = this,
- sup = this._super;
- $.when(this.languages_loaded).then(function() {
- if (self.view.translatable_fields && self.view.translatable_fields.length) {
- self.do_load_fields_values(function() {
- sup.call(self);
- if (field) {
- // TODO: focus and scroll to field
- }
- });
- } else {
- sup.call(self);
- }
- });
- },
- on_button_Save: function() {
- var trads = {},
- self = this;
- self.$fields_form.find('.oe_trad_field.touched').each(function() {
- var field = $(this).attr('name').split('-');
- if (!trads[field[0]]) {
- trads[field[0]] = {};
- }
- trads[field[0]][field[1]] = $(this).val();
- });
- _.each(trads, function(data, code) {
- if (code === self.view_language) {
- _.each(data, function(value, field) {
- self.view.fields[field].set_value(value);
- });
- } else {
- self.view.dataset.write(self.view.datarecord.id, data, { 'lang': code });
- }
- });
- this.close();
- },
- on_button_Close: function() {
- this.close();
- }
-});
-
-openerp.base.View = openerp.base.Widget.extend({
- set_default_options: function(options) {
- this.options = options || {};
- _.defaults(this.options, {
- // All possible views options should be defaulted here
- sidebar_id: null,
- sidebar: true,
- action: null,
- action_views_ids: {}
- });
- },
- open_translate_dialog: function(field) {
- if (!this.translate_dialog) {
- this.translate_dialog = new openerp.base.TranslateDialog(this).start();
- }
- this.translate_dialog.open(field);
- },
- /**
- * Fetches and executes the action identified by ``action_data``.
- *
- * @param {Object} action_data the action descriptor data
- * @param {String} action_data.name the action name, used to uniquely identify the action to find and execute it
- * @param {String} [action_data.special=null] special action handlers (currently: only ``'cancel'``)
- * @param {String} [action_data.type='workflow'] the action type, if present, one of ``'object'``, ``'action'`` or ``'workflow'``
- * @param {Object} [action_data.context=null] additional action context, to add to the current context
- * @param {openerp.base.DataSet} dataset a dataset object used to communicate with the server
- * @param {Object} [record_id] the identifier of the object on which the action is to be applied
- * @param {Function} on_closed callback to execute when dialog is closed or when the action does not generate any result (no new action)
- */
- execute_action: function (action_data, dataset, record_id, on_closed) {
- var self = this;
- var handler = function (r) {
- var action = r.result;
- if (action && action.constructor == Object) {
- action.context = action.context || {};
- _.extend(action.context, {
- active_id: record_id || false,
- active_ids: [record_id || false],
- active_model: dataset.model
- });
- self.do_action(action, on_closed);
- } else if (on_closed) {
- on_closed(action);
- }
- };
-
- var context = new openerp.base.CompoundContext(dataset.get_context(), action_data.context || {});
-
- if (action_data.special) {
- handler({result: {"type":"ir.actions.act_window_close"}});
- } else if (action_data.type=="object") {
- return dataset.call_button(action_data.name, [[record_id], context], handler);
- } else if (action_data.type=="action") {
- return this.rpc('/base/action/load', { action_id: parseInt(action_data.name, 10), context: context }, handler);
- } else {
- return dataset.exec_workflow(record_id, action_data.name, handler);
- }
- },
- /**
- * Directly set a view to use instead of calling fields_view_get. This method must
- * be called before start(). When an embedded view is set, underlying implementations
- * of openerp.base.View must use the provided view instead of any other one.
- *
- * @param embedded_view A view.
- */
- set_embedded_view: function(embedded_view) {
- this.embedded_view = embedded_view;
- this.options.sidebar = false;
- },
- do_switch_view: function(view) {
- },
- set_common_sidebar_sections: function(sidebar) {
- sidebar.add_section('customize', "Customize", [
- {
- label: "Manage Views",
- callback: this.on_sidebar_manage_view,
- title: "Manage views of the current object"
- }, {
- label: "Edit Workflow",
- callback: this.on_sidebar_edit_workflow,
- title: "Manage views of the current object",
- classname: 'oe_hide oe_sidebar_edit_workflow'
- }, {
- label: "Customize Object",
- callback: this.on_sidebar_customize_object,
- title: "Manage views of the current object"
- }
- ]);
- sidebar.add_section('other', "Other Options", [
- {
- label: "Import",
- callback: this.on_sidebar_import
- }, {
- label: "Export",
- callback: this.on_sidebar_export
- }, {
- label: "Translate",
- callback: this.on_sidebar_translate,
- classname: 'oe_sidebar_translate oe_hide'
- }, {
- label: "View Log",
- callback: this.on_sidebar_view_log,
- classname: 'oe_hide oe_sidebar_view_log'
- }
- ]);
- },
- on_sidebar_manage_view: function() {
- if (this.fields_view && this.fields_view.arch) {
-// $('<xmp>' + openerp.base.json_node_to_xml(this.fields_view.arch, true) + '</xmp>').dialog({ width: '95%', height: 600});
- var view_editor = new openerp.base.ViewEditor(this, this.$element, this.dataset, this.fields_view.arch)
- view_editor.start();
- } else {
- this.notification.warn("Manage Views", "Could not find current view declaration");
- }
- },
- on_sidebar_edit_workflow: function() {
- this.log('Todo');
- },
- on_sidebar_customize_object: function() {
- this.log('Todo');
- },
- on_sidebar_import: function() {
- },
- on_sidebar_export: function() {
- var export_view = new openerp.base.DataExport(this, this.dataset);
- export_view.start();
- },
- on_sidebar_translate: function() {
- this.open_translate_dialog();
- },
- on_sidebar_view_log: function() {
- }
-});
-
-/**
- * Registry for all the main views
- */
-openerp.base.views = new openerp.base.Registry();
-
-openerp.base.json_node_to_xml = function(node, single_quote, indent) {
- // For debugging purpose, this function will convert a json node back to xml
- // Maybe usefull for xml view editor
- if (typeof(node.tag) !== 'string' || !node.children instanceof Array || !node.attrs instanceof Object) {
- throw("Node a json node");
- }
- indent = indent || 0;
- var sindent = new Array(indent + 1).join('\t'),
- r = sindent + '<' + node.tag;
- for (var attr in node.attrs) {
- var vattr = node.attrs[attr];
- if (typeof(vattr) !== 'string') {
- // domains, ...
- vattr = JSON.stringify(vattr);
- }
- vattr = vattr.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
- if (single_quote) {
- vattr = vattr.replace(/&quot;/g, "'");
- }
- r += ' ' + attr + '="' + vattr + '"';
- }
- if (node.children.length) {
- r += '>\n';
- var childs = [];
- for (var i = 0, ii = node.children.length; i < ii; i++) {
- childs.push(openerp.base.json_node_to_xml(node.children[i], single_quote, indent + 1));
- }
- r += childs.join('\n');
- r += '\n' + sindent + '</' + node.tag + '>';
- return r;
- } else {
- return r + '/>';
- }
-}
-
-};
-
-// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml
deleted file mode 100644
index 48b6473feec..00000000000
--- a/addons/base/static/src/xml/base.xml
+++ /dev/null
@@ -1,1401 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vim:fdl=1:
--->
-<templates id="template" xml:space="preserve">
-<t t-name="Interface">
- <div id="oe_loading" class="loading"></div>
- <div id="oe_notification" class="oe_notification">
- <div id="oe_notification_default">
- <a class="ui-notify-cross ui-notify-close" href="#">x</a>
- <h1>#{title}</h1>
- <p>#{text}</p>
- </div>
- <div id="oe_notification_alert" class="ui-state-error">
- <a class="ui-notify-cross ui-notify-close" href="#">x</a>
- <span style="float:left; margin:2px 5px 0 0;" class="ui-icon ui-icon-alert"></span>
- <h1>#{title}</h1>
- <p>#{text}</p>
- </div>
- </div>
- <table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%" class="main_table">
- <tr>
- <td colspan="2" valign="top">
- <div id="oe_header" class="header"></div>
- <div id="oe_menu" class="menu"></div>
- </td>
- </tr>
- <tr>
- <td valign="top" class="login-container" colspan="2">
- <div id="oe_login" class="login"></div>
- </td>
- </tr>
- <tr class="db_options_row">
- <td valign="top" class="db_container">
- <div id="oe_database" class="database"></div>
- </td>
- <td valign="top">
- <div id="oe_db_options"></div>
- </td>
- </tr>
- <tr>
- <td valign="top" id="oe_secondary_menu" class="secondary_menu">
- </td>
- <td valign="top">
- <div id="oe_app" class="oe-application">
- </div>
- </td>
- </tr>
- <tr>
- <td colspan="2">
- <div id="oe_footer" class="oe_footer">
- <p class="oe_footer_powered">Powered by <a href="http://www.openerp.com">openerp.com</a>.</p>
- </div>
- </td>
- </tr>
- </table>
-</t>
-<t t-name="Loading">
- Loading...
-</t>
-<t t-name="Database">
- <ul class="db_options" style="padding: 0px; display: inline;">
- <li id="db-create">Create</li>
- <li id="db-drop">Drop</li>
- <li id="db-backup">Backup</li>
- <li id="db-restore">Restore</li>
- <li id="db-change-password">Password</li>
- <li id="back-to-login">Back to Login</li>
- </ul>
-</t>
-<t t-name="Database.CreateDB">
- <form name="create_db_form" class="oe_forms" method="POST">
- <table width="100%">
- <tr>
- <td class="option_string">
- CREATE DATABASE
- </td>
- </tr>
- </table>
- <table align="center" class="db_option_table">
- <tr>
- <td><label for="super_admin_pwd">Master password:</label></td>
- <td><input type="password" name="super_admin_pwd" class="required" value="admin"/></td>
- </tr>
- <tr>
- <td><label for="db_name">New database name:</label></td>
- <td><input type="text" name="db_name" class="required"/></td>
- </tr>
- <tr>
- <td><label for="demo_data">Load Demonstration data:</label></td>
- <td><input type="checkbox" name="demo_data"/></td>
- </tr>
- <tr>
- <td><label for="db_lang">Default language:</label></td>
- <td>
- <select name="db_lang" t-if="lang_list">
- <t t-foreach="lang_list" t-as="lang">
- <option t-att-value="lang[0]" t-att-selected="lang[0] === 'en_US' ? 'selected' : undefined"><t t-esc="lang[1]"/></option>
- </t>
- </select>
- </td>
- </tr>
- <tr>
- <td><label for="create_admin_pwd">Admin password:</label></td>
- <td><input type="password" name="create_admin_pwd" class="required"/></td>
- </tr>
- <tr>
- <td><label for="create_confirm_pwd">Confirm password:</label></td>
- <td><input type="password" name="create_confirm_pwd" class="required"
- equalTo="input[name=create_admin_pwd]"/></td>
- </tr>
- <tr>
- <td colspan="2" align="right"><input type="submit" value="Create"/></td>
- </tr>
- </table>
- </form>
-</t>
-<t t-name="DropDB">
- <form name="drop_db_form" class="oe_forms" method="POST">
- <table width="100%">
- <tr>
- <td class="option_string">
- DROP DATABASE
- </td>
- </tr>
- </table>
- <table align="center" class="db_option_table">
- <tr>
- <td><label for="drop_db">Database:</label></td>
- <td>
- <select t-if="db_list" name="drop_db" autofocus="autofocus">
- <t t-foreach="db_list" t-as="db">
- <option t-att-value="db"><t t-esc="db"/></option>
- </t>
- </select>
- </td>
- </tr>
- <tr>
- <td><label for="drop_password">Master Password:</label></td>
- <td><input type="password" name="drop_pwd" class="required"/></td>
- </tr>
- <tr>
- <td colspan="2" align="right"><input type="submit" value="Drop"/></td>
- </tr>
- </table>
- </form>
-</t>
-<t t-name="BackupDB">
- <form name="backup_db_form" class="oe_forms" method="POST" target="backup-target"
- action="/base/database/backup">
- <input type="hidden" name="token"/>
- <table width="100%">
- <tr>
- <td class="option_string">
- BACKUP DATABASE
- </td>
- </tr>
- </table>
- <table align="center" class="db_option_table">
- <tr>
- <td><label for="backup_db">Database:</label></td>
- <td>
- <select t-if="db_list" name="backup_db" autofocus="autofocus">
- <t t-foreach="db_list" t-as="db">
- <option t-att-value="db"><t t-esc="db"/></option>
- </t>
- </select>
- </td>
- </tr>
- <tr>
- <td><label for="backup_pwd">Master Password:</label></td>
- <td><input type="password" name="backup_pwd" class="required"/></td>
- </tr>
- <tr>
- <td colspan="2" align="right"><input type="submit" value="Backup"/></td>
- </tr>
- </table>
- </form>
-</t>
-<t t-name="RestoreDB">
- <form name="restore_db_form" class="oe_forms" method="POST">
- <table width="100%">
- <tr>
- <td class="option_string">
- RESTORE DATABASE
- </td>
- </tr>
- </table>
- <table align="center" class="db_option_table">
- <tr>
- <td><label for="restore_db">File:</label></td>
- <td><input type="file" name="db_file" class="required"
- autofocus="autofocus"/></td>
- </tr>
- <tr>
- <td><label for="restore_pwd">Master Password:</label></td>
- <td><input type="password" name="restore_pwd" class="required"/></td>
- </tr>
- <tr>
- <td><label for="new_db">New database name:</label></td>
- <td><input type="text" name="new_db" class="required"/></td>
- </tr>
- <tr>
- <td colspan="2" align="right"><input type="submit" value="Restore"/></td>
- </tr>
- </table>
- </form>
-</t>
-<t t-name="Change_DB_Pwd">
- <form name="change_pwd_form" class="oe_forms" method="POST">
- <table width="100%">
- <tr>
- <td class="option_string">
- CHANGE MASTER PASSWORD
- </td>
- </tr>
- </table>
- <table align="center" class="db_option_table">
- <tr>
- <td><label for="old_pwd">Master password:</label></td>
- <td><input type="password" name="old_pwd" class="required"
- minlength="1" autofocus="autofocus"/></td>
- </tr>
- <tr>
- <td><label for="new_pwd">New master password:</label></td>
- <td><input type="password" name="new_pwd" class="required"
- minlength="1"/></td>
- </tr>
- <tr>
- <td><label for="confirm_pwd">Confirm new master password:</label></td>
- <td><input type="password" name="confirm_pwd" class="required"
- equalTo="input[name=new_pwd]" minlength="1"/></td>
- </tr>
- <tr>
- <td colspan="2" align="right"><input type="submit" value="Change Password"/></td>
- </tr>
- </table>
- </form>
-</t>
-<t t-name="Login">
- <form class="oe_forms">
- <fieldset>
- <legend style="">
- <img src="/base/static/src/img/stock_person.png" alt="" />
- </legend>
- <div class="oe_box2">
- <table align="center" cellspacing="2px" cellpadding="0">
- <tr>
- <td><label for="db">Database:</label></td>
- <td>
- <t t-if="!db_list">
- <input type="text" name="db" t-att-value="selected_db || ''" autofocus="true"/>
- </t>
- <t t-if="db_list">
- <select name="db">
- <t t-foreach="db_list" t-as="db">
- <t t-if="selected_db === db">
- <option t-att-value="db" selected="true">
- <t t-esc="db"/></option>
- </t>
- <t t-if="selected_db !== db">
- <option t-att-value="db"><t t-esc="db"/></option>
- </t>
- </t>
- </select>
- </t>
- </td>
- </tr>
- <tr>
- <td><label for="login">User:</label></td>
- <td><input type="text" name="login"
- t-att-value="selected_login || ''" autofocus="true"/></td>
- </tr>
- <tr>
- <td><label for="password">Password:</label></td>
- <td><input type="password" name="password"
- t-att-value="selected_password || ''"/></td>
- </tr>
- <tr>
- <td></td>
- <td>
- <button type="button" id="oe-db-config">Database</button>
- <button type="submit" name="submit">Login</button>
- </td>
- </tr>
- </table>
- </div>
- </fieldset>
- <div class="login_error_message">Bad username or password</div>
- </form>
- <div class="oe_login_right_pane">
- <p>We think that daily job activities can be more intuitive, efficient, automated, .. and even fun.</p>
- <h3>OpenERP's vision to be:</h3>
-
- <table cellpadding="0" cellspacing="0" width="100%" style="border:none;">
- <tbody>
- <tr>
- <td>
- <img src="/base/static/src/img/product.png"/>
- </td>
- <td>
- <strong>Full featured</strong><br />
- Today's enterprise challenges are multiple. We provide one module for each need.
- </td>
- </tr>
- <tr>
- <td>
- <img src="/base/static/src/img/accessories-archiver.png"/>
- </td>
- <td>
- <strong>Open Source</strong><br />
- To Build a great product, we rely on the knowledge of thousands of contributors.
- </td>
- </tr>
- <tr>
- <td>
- <img src="/base/static/src/img/partner.png" />
- </td>
- <td>
- <strong>User Friendly</strong><br />
- In order to be productive, people need clean and easy to use interface.
- </td>
- </tr>
- </tbody>
- </table>
-
- </div>
-</t>
-<t t-name="Header">
- <div>
- <a t-att-href="'/' + widget.qs" class="company_logo_link">
- <div class="company_logo" />
- </a>
- </div>
-</t>
-<t t-name="Header-content">
- <h1 class="header_title">
- <span class="database"><t t-esc="widget.session.db"/></span> - <t t-esc="widget.session.login"/> <br/>
- <small class="username">rpc_session_id: <t t-esc="widget.session.session_id"/></small>
- </h1>
- <div class="header_corner">
- <ul class="block">
- <li>
- <a href="#home" title="Home" class="home"><img src="/base/static/src/img/header-home.png" width="16" height="16" border="0"/></a>
- </li>
- <li>
- <a href="#requests" title="Requests" class="requests"><img src="/base/static/src/img/header-requests.png" width="16" height="16" border="0"/><small>1</small></a>
- </li>
- <li class="preferences">
- <a href="#preferences" title="Preferences" class="preferences"><img src="/base/static/src/img/header-preferences.png" width="16" height="16" border="0"/></a>
- </li>
- <li>
- <a href="#about" title="About" class="about"><img src="/base/static/src/img/header-about.png" width="16" height="16" border="0"/></a>
- </li>
- <li>
- <a href="http://doc.openerp.com/v6.0/book?version=$version" title="Help" target="_blank" class="help"><img src="/base/static/src/img/header-help.png" width="16" height="16" border="0"/></a>
- </li>
- </ul>
- <div class="block">
- <a href="#logout" class="logout">LOGOUT</a>
- </div>
-
- </div>
- <div class="oe-shortcuts"> </div>
-</t>
-<ul t-name="Shortcuts">
- <li t-foreach="shortcuts" t-as="shortcut"
- t-att-data-id="shortcut.res_id"
- t-att-data-shortcut-id="shortcut.id"
- ><t t-esc="shortcut.name"/></li>
-</ul>
-<t t-name="Menu">
- <table align="center">
- <tr>
- <t t-foreach="data.children" t-as="menu">
- <td>
- <a href="#" t-att-data-menu="menu.id">
- <t t-esc="menu.name"/>
- </a>
- </td>
- </t>
- </tr>
- </table>
-</t>
-<t t-name="Menu.secondary">
- <div style="display: none" class="menu_accordion" t-att-data-menu-parent="menu.id">
- <t t-foreach="menu.children" t-as="menu">
- <t t-set="header">h3</t>
- <t t-call="Menu.secondary.children"/>
- </t>
- </div>
-</t>
-<t t-name="Menu.secondary.children">
- &lt;<t t-esc="header"/>&gt;
- <a href="#" t-attf-id="menu_#{menu.id}">
- <span><t t-esc="menu.name"/></span>
- </a>
- &lt;/<t t-esc="header"/>&gt;
- <div class="menu_content">
- <t t-foreach="menu.children" t-as="menu">
- <t t-if="!menu.children.length">
- <a href="#" class="leaf" t-att-data-menu="menu.id">
- <span><t t-esc="menu.name"/></span>
- </a>
- </t>
- <t t-if="menu.children.length">
- <div class="submenu_accordion">
- <t t-call="Menu.secondary.children">
- <t t-set="header">h4</t>
- </t>
- </div>
- </t>
- </t>
- </div>
-</t>
-<t t-name="ViewManager">
- <table class="view-manager-main-table">
- <tr>
- <td class="view-manager-main-content">
- <a class="oe-shortcut-toggle" title="Add / Remove Shortcut..."
- href="javascript: void(0)"> </a>
- <div class="oe_vm_switch">
- <t t-if="views.length != 1" t-foreach="views" t-as="view">
- <button type="button" t-att-data-view-type="view.view_type">
- <t t-esc="view.view_type"/>
- </button>
- </t>
- </div>
- <div t-attf-id="#{prefix}_search" t-opentag="true"/>
- <t t-foreach="views" t-as="view">
- <div t-attf-id="#{prefix}_view_#{view.view_type}"/>
- </t>
- </td>
- <td class="view-manager-main-sidebar" height="100%">
- <t t-foreach="views" t-as="view">
- <div t-attf-id="#{prefix}_sidebar_#{view.view_type}" class="sidebar-main-div closed-sidebar" style="display: none"/>
- </t>
- </td>
- </tr>
- </table>
-</t>
-<t t-name="Sidebar">
- <a class="toggle-sidebar"></a>
- <div class="sidebar-content">
- <div class="sidebar-actions">
- </div>
- </div>
-</t>
-<t t-name="Sidebar.section">
- <h2><t t-esc="name"/></h2>
- <div t-att-id="section_id" t-att-class="classname">
- <ul t-if="items">
- <li t-foreach="items" t-as="item" t-att-class="item.classname">
- <a class="oe_sidebar_action_a" t-att-id="item.element_id" t-att-title="item.title" href="#">
- <t t-esc="item.label"/>
- </a>
- </li>
- </ul>
- </div>
-</t>
-<t t-name="TranslateDialog">
- <ul class="oe_translate_tabs">
- <li><a t-attf-href="##{widget.element_id}_fields">Fields</a></li>
- <li><a t-attf-href="##{widget.element_id}_view">View labels</a></li>
- <li><a t-attf-href="##{widget.element_id}_sidebar">Sidebar Relates</a></li>
- </ul>
- <div t-attf-id="#{widget.element_id}_fields">
- <table t-if="widget.view.translatable_fields" class="oe_frame oe_forms oe_translation_form" border="0" cellpadding="0" cellspacing="0" width="100%">
- <tr>
- <td class="oe_form_separator" width="1%" nowrap="nowrap">
- <div class="separator horizontal">Field</div>
- </td>
- <th t-foreach="widget.languages" align="left">
- <div class="separator horizontal"><t t-esc="name"/></div>
- </th>
- </tr>
- <tr t-foreach="widget.view.translatable_fields" t-as="field">
- <td class="oe_form_frame_cell" width="1%" nowrap="nowrap">
- <label class="oe_label"><t t-esc="field.string"/>:</label>
- </td>
- <td t-foreach="widget.languages" t-as="lg" class="oe_form_frame_cell">
- <input t-if="field.type == 'char'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" data-value="" class="oe_trad_field" style="width: 100%"/>
- <textarea t-if="field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" data-value="" class="oe_trad_field" style="width: 100%"></textarea>
- </td>
- </tr>
- </table>
- </div>
- <div t-attf-id="#{widget.element_id}_view">
- Translate view
- </div>
- <div t-attf-id="#{widget.element_id}_sidebar">
- Translate sidebar
- </div>
-</t>
-<t t-name="TreeView">
- <h2 class="oe_view_title"><t t-esc="title"/></h2>
- <select t-if="toolbar" style="width: 30%">
- </select>
- <table class="oe-treeview-table">
- <thead>
- <tr>
- <th t-foreach="fields_view" t-as="field"
- t-if="!field.attrs.modifiers.tree_invisible"
- class="treeview-header">
- <t t-esc="fields[field.attrs.name].string" />
- </th>
- </tr>
- </thead>
- <tbody>
- </tbody>
- </table>
-</t>
-<tr t-name="TreeView.rows"
- t-foreach="records" t-as="record"
- t-att-id="'treerow_' + record.id"
- t-att-data-id="record.id" t-att-data-level="level + 1">
- <t t-set="children" t-value="record[children_field]"/>
- <t t-set="has_children" t-value="children and children.length"/>
-
- <td t-foreach="fields_view" t-as="field"
- t-if="!field.attrs.modifiers.tree_invisible"
- t-att-data-id="record.id"
- t-att-style="!field_index ? 'background-position: ' + 19*level + 'px; padding-left: ' + 19*level + 'px' : undefined"
- t-att-class="!field_index and has_children ? 'treeview-tr' : 'treeview-td'">
- <span t-if="!field.attrs.modifiers.invisible">
- <t t-esc="render(record[field.attrs.name], fields[field.attrs.name])" />
- </span>
- </td>
-</tr>
-<table t-name="ListView" class="oe-listview-content">
- <t t-set="columns_count" t-value="visible_columns.length + (options.selectable ? 1 : 0) + (options.deletable ? 1 : 0)"/>
- <thead class="ui-widget-header">
- <tr t-if="options.action_buttons !== false or options.pager !== false">
- <th t-att-colspan="columns_count">
- <table>
- <tr>
- <td t-if="options.action_buttons !== false" class="oe-actions">
- <button type="button" class="oe-list-add"
- t-if="options.addable">
- <t t-esc="options.addable"/>
- </button>
- <button type="button" class="oe-list-delete"
- t-if="options.selectable and options.deletable">
- Delete
- </button>
- </td>
- <th t-if="options.pager !== false" class="oe-list-pager">
- <button type="button" disabled="disabled"
- data-pager-action="first">First</button>
- <button type="button" disabled="disabled"
- data-pager-action="previous"
- >&lt;</button>
-
- <span class="oe-pager-state">
- </span>
-
- <button type="button" disabled="disabled"
- data-pager-action="next">&gt;</button>
- <button type="button" disabled="disabled"
- data-pager-action="last">Last</button>
- </th>
- </tr>
- </table>
- </th>
- </tr>
- <tr t-if="options.header">
- <t t-foreach="columns" t-as="column">
- <th t-if="column.meta">
- <t t-esc="column.string"/>
- </th>
- </t>
- <th t-if="options.selectable" width="1"/>
- <t t-foreach="columns" t-as="column">
- <th t-if="!column.meta and column.invisible !== '1'" t-att-data-id="column.id"
- t-att-class="((options.sortable and column.tag !== 'button') ? 'oe-sortable' : null)">
- <t t-if="column.tag !== 'button'"
- ><t t-esc="column.string"/></t>
- </th>
- </t>
- <th t-if="options.deletable" width="1"/>
- </tr>
- </thead>
- <tfoot class="ui-widget-header">
- <tr>
- <td t-if="options.selectable"/>
- <td t-foreach="aggregate_columns" t-as="column" class="oe-list-footer oe-number"
- t-att-data-field="column.id" t-att-title="column.label">
- </td>
- <td t-if="options.deletable"/>
- </tr>
- </tfoot>
-</table>
-<t t-name="ListView.rows" t-foreach="records.length" t-as="index">
- <t t-call="ListView.row">
- <t t-set="record" t-value="records.at(index)"/>
- <t t-set="row_parity" t-value="index_parity"/>
- </t>
-</t>
-<tr t-name="ListView.row" t-att-class="row_parity"
- t-att-data-id="record.get('id')">
- <t t-foreach="columns" t-as="column">
- <td t-if="column.meta">
-
- </td>
- </t>
- <t t-if="options.radio">
- <th t-if="options.selectable" class="oe-record-selector" width="1">
- <input type="radio" name ="radiogroup"/>
- </th>
- </t>
- <t t-if="!options.radio">
- <th t-if="options.selectable" class="oe-record-selector" width="1">
- <input type="checkbox"/>
- </th>
- </t>
-
-
- <t t-foreach="columns" t-as="column">
- <t t-set="align" t-value="column.type === 'integer' or column.type == 'float'"/>
- <td t-if="!column.meta and column.invisible !== '1'" t-att-title="column.help"
- t-att-class="'oe-field-cell' + (align ? ' oe-number' : '')"
- t-att-data-field="column.id">
- <t t-raw="render_cell(record.toForm().data, column)"/>
- </td>
- </t>
- <td t-if="options.deletable" class='oe-record-delete' width="1">
- <button type="button" name="delete">♻</button>
- </td>
-</tr>
-<t t-name="ListView.row.form">
- <t t-raw="frame.render()"/>
-</t>
-<t t-name="FormView">
- <div class="oe_form_header" t-att-id="view.element_id + '_header'">
- <h2 class="oe_view_title"><t t-esc="view.fields_view.arch.attrs.string"/> <button t-if="view.session.debug" class="oe_get_xml_view">View#<t t-esc="view.fields_view.view_id"/></button></h2>
- <div class="oe_form_buttons" t-if="view.options.action_buttons !== false">
- <!--<button type="button" class="oe_form_button_save">
- <span class="oe_form_on_update">Save</span>
- <span class="oe_form_on_create">Create</span>
- </button>-->
- <button type="button" class="oe_form_button_save_edit">
- <span class="oe_form_on_update">Save &amp; Edit</span>
- <span class="oe_form_on_create">Create &amp; Edit</span>
- </button>
- <!--<button type="button" class="oe_form_button_cancel">Cancel</button>-->
- <button type="button" class="oe_form_button_new">New</button>
- </div>
- <div class="oe_form_pager" t-if="view.options.pager !== false">
- <button type="button" data-pager-action="first">First</button>
- <button type="button" data-pager-action="previous">&lt;&lt;</button>
-
- <span class="oe_pager_index">0</span> / <span class="oe_pager_count">0</span>
-
- <button type="button" data-pager-action="next">&gt;&gt;</button>
- <button type="button" data-pager-action="last">Last</button>
- </div>
- </div>
- <t t-raw="frame.render()"/>
-</t>
-<t t-name="FormView.sidebar.attachments">
- <div class="oe-sidebar-attachments-toolbar">
- <div class="oe-binary-file-set" style="float: right">
- <form class="oe-binary-form" t-attf-target="#{element_id}_iframe"
- method="post" enctype="multipart/form-data" action="/base/binary/upload_attachment">
- <input type="hidden" name="session_id" t-att-value="session.session_id"/>
- <input type="hidden" name="callback" t-attf-value="#{element_id}_iframe"/>
- <input type="hidden" name="model" t-att-value="view.dataset.model"/>
- <input type="hidden" name="id" t-att-value="view.datarecord.id"/>
- <button class="button" type="button">
- <img src="/base/static/src/img/throbber.gif" width="16" height="16" style="display: none"/>
- <span>Add</span>
- </button>
- <input type="file" class="oe-binary-file" name="ufile" title="Add attachment"
- t-att-onclick="view.datarecord.id ? null : 'alert(\'No record selected ! You can only attach to existing record.\'); return false;'"/>
- </form>
- <iframe t-attf-id="#{element_id}_iframe" t-attf-name="#{element_id}_iframe" style="display: none"> </iframe>
- </div>
- </div>
- <br style="clear: both"/>
- <ul class="oe-sidebar-attachments-items">
- <li t-foreach="attachments" t-as="attachment">
- <t t-if="attachment.type == 'binary'" t-set="attachment.url" t-value="'/base/binary/saveas?session_id='
- + session.session_id + '&amp;model=ir.attachment&amp;id=' + attachment.id
- + '&amp;field=datas&amp;fieldname=name&amp;t=' + (new Date().getTime())"/>
- <a class="oe-sidebar-attachments-link" t-att-href="attachment.url" target="_blank">
- <t t-esc="attachment.name"/>
- </a>
- <a href="#" class="oe-sidebar-attachment-delete" t-att-data-id="attachment.id" t-attf-title="Delete the attachment #{attachment.name}">
- <img src="/base/static/src/img/attachments-close.png" width="15" height="15" border="0"/>
- </a>
- </li>
- </ul>
-</t>
-<t t-name="Widget">
- Unhandled widget
- <t t-raw="console.log('Unhandled widget', widget)"/>
-</t>
-<t t-name="WidgetFrame">
- <table border="0" width="100%" cellpadding="0" cellspacing="0" class="oe_frame oe_forms">
- <tr t-foreach="widget.table" t-as="row">
- <t t-foreach="row" t-as="td">
- <td t-att-colspan="td.colspan gt 1 ? td.colspan : undefined"
- t-att-width="td.width"
- t-att-nowrap="td.nowrap or td.is_field_m2o? 'true' : undefined"
- t-att-valign="td.table ? 'top' : undefined"
- t-att-id="td.element_id"
- t-attf-class="oe_form_frame_cell #{td.classname}"
- >
- <t t-raw="td.render()"/>
- </td>
- </t>
- </tr>
- </table>
-</t>
-<t t-name="WidgetNotebook">
- <ul>
- <li t-foreach="widget.pages" t-as="page" t-att-id="page.element_tab_id">
- <a t-att-href="'#' + page.element_id">
- <t t-esc="page.string"/>
- </a>
- </li>
- </ul>
- <t t-foreach="widget.pages" t-as="page">
- <t t-raw="page.render()"/>
- </t>
-</t>
-<t t-name="WidgetNotebookPage">
- <div t-att-id="widget.element_id">
- <t t-call="WidgetFrame"/>
- </div>
-</t>
-<t t-name="WidgetSeparator">
- <div t-if="widget.orientation !== 'vertical'" t-att-class="'separator ' + widget.orientation">
- <t t-esc="widget.string"/>
- </div>
-</t>
-<t t-name="WidgetLabel">
- <label t-att-for="widget.element_id + '_field'"
- t-att-class="'oe_label' + (widget.help ? '_help' : '')"
- t-att-title="widget.help">
- <t t-esc="widget.string"/>
- <span t-if="widget.help">?</span>
- <t t-if="widget.string and widget.node.tag != 'label'">:</t>
- </label>
-</t>
-<t t-name="WidgetParagraph">
- <p class="oe_form_paragraph"><t t-esc="widget.string"/></p>
-</t>
-<t t-name="FieldChar">
- <input type="text" size="1"
- t-att-name="widget.name"
- t-att-id="widget.element_id + '_field'"
- t-att-class="'field_' + widget.type"
- t-attf-style="width: #{widget.field.translate ? '99' : '100'}%"
- />
- <img class="oe_field_translate" t-if="widget.field.translate" src="/base/static/src/img/icons/terp-translate.png" width="16" height="16" border="0"/>
-</t>
-<t t-name="FieldEmail">
- <table cellpadding="0" cellspacing="0" border="0" width="100%">
- <tr>
- <td width="100%">
- <t t-call="FieldChar"/>
- </td>
- <td width="16">
- <button type="button" class="button" title="Send an e-mail with your default e-mail client">
- <img src="/base/static/src/img/icons/terp-mail-message-new.png"/>
- </button>
- </td>
- </tr>
- </table>
-</t>
-<t t-name="FieldUrl">
- <table cellpadding="0" cellspacing="0" border="0" width="100%">
- <tr>
- <td width="100%">
- <t t-call="FieldChar"/>
- </td>
- <td width="16">
- <button type="button" class="button" title="Open this resource">
- <img src="/base/static/src/img/icons/gtk-ok.png"/>
- </button>
- </td>
- </tr>
- </table>
-</t>
-<t t-name="FieldText">
- <textarea rows="6"
- t-att-name="widget.name"
- t-att-id="widget.element_id + '_field'"
- t-att-class="'field_' + widget.type"
- t-attf-style="width: #{widget.field.translate ? '99' : '100'}%"
- ></textarea>
- <img class="oe_field_translate" t-if="widget.field.translate" src="/base/static/src/img/icons/terp-translate.png" width="16" height="16" border="0"/>
-</t>
-<t t-name="FieldDate">
- <input type="text" size="1" style="width: 100%"
- t-att-name="widget.name"
- t-att-id="widget.element_id + '_field'"
- t-att-class="'field_' + widget.type"
- />
-</t>
-<t t-name="FieldSelection">
- <select
- t-att-name="widget.name"
- t-att-id="widget.element_id + '_field'"
- t-att-class="'field_' + widget.type"
- style="width: 100%">
- <t t-foreach="widget.field_index" t-as="options">
- <option t-att-value="options.ikey">
- <t t-esc="options.label"/>
- </option>
- </t>
- </select>
-</t>
-<t t-name="FieldMany2One">
- <div t-att-id="widget.element_id" class="oe-m2o">
- <input t-att-id="widget.element_id + '_input'" type="text" size="1" style="width: 100%;"/>
- <span class="oe-m2o-drop-down-button" t-att-id="widget.element_id + '_drop_down'">
- <img src="/base/static/src/img/down-arrow.png" /></span>
- <span class="oe-m2o-cm-button" t-att-id="widget.name + '_open'">
- <img src="/base/static/src/img/icons/gtk-index.png"/></span>
- <div t-att-id="widget.cm_id" class="contextMenu" style="display:none">
- </div>
- </div>
-</t>
-<t t-name="FieldMany2One.context_menu">
- <ul>
- <li t-att-id="widget.cm_id + '_open'" style="color:grey">Open...</li>
- <li t-att-id="widget.cm_id + '_create'">Create...</li>
- <li t-att-id="widget.cm_id + '_search'" class="oe_m2o_menu_item_mandatory">Search...</li>
- <t t-set="i" t-value="0"/>
- <t t-foreach="widget.related_entries" t-as="entry">
- <li t-att-id="widget.cm_id + '_related_' + i" style="color:grey" class="oe_m2o_menu_item_mandatory">
- ... <t t-esc="(entry[2] || {})['name'] || ''"/>
- </li>
- <t t-set="i" t-value="i+1"/>
- </t>
- </ul>
-</t>
-<t t-name="FieldOne2Many">
- <div t-att-id="widget.element_id">
- </div>
-</t>
-<t t-name="FieldMany2Many">
- <div t-att-id="widget.list_id"></div>
-</t>
-<t t-name="FieldReference">
- <table border="0" width="100%" cellpadding="0" cellspacing="0" class="oe_frame oe_forms">
- <tr>
- <td t-att-id="widget.selection.element_id" class="oe_form_frame_cell oe_form_selection">
- <t t-raw="widget.selection.render()"/>
- </td>
- <td t-att-id="widget.m2o.element_id" class="oe_form_frame_cell oe_form_many2one" nowrap="true">
- <t t-raw="widget.m2o.render()"/>
- </td>
- </tr>
- </table>
-</t>
-<t t-name="FieldBoolean">
- <input type="checkbox"
- t-att-name="widget.name"
- t-att-id="widget.element_id + '_field'"
- t-att-class="'field_' + widget.type"/>
-</t>
-<t t-name="FieldProgressBar">
- <div t-opentag="true" class="oe-progressbar">
- <span></span>
- </div>
-</t>
-<t t-name="FieldBinaryImage">
- <table cellpadding="0" cellspacing="0" border="0">
- <tr>
- <td align="center">
- <img src="/base/static/src/img/placeholder.png" class="oe-binary-image"
- t-att-border="widget.readonly ? 0 : 1"
- t-att-id="widget.element_id + '_field'"
- t-att-name="widget.name"
- t-att-class="'field_' + widget.type"
- t-att-width="widget.node.attrs.img_width || widget.node.attrs.width"
- t-att-height="widget.node.attrs.img_height || widget.node.attrs.height"
- />
- </td>
- </tr>
- <tr>
- <td align="center" valign="bottom" height="25">
- <div class="oe-binary">
- <table cellspacing="0" cellpadding="0" border="0">
- <tr>
- <td>
- <div class="oe-binary-file-set" style="width: 40px; height:22px;">
- <form class="oe-binary-form" t-att-target="widget.iframe"
- method="post" enctype="multipart/form-data" action="/base/binary/upload">
- <input type="hidden" name="session_id" value=""/>
- <input type="hidden" name="callback" t-att-value="widget.iframe"/>
- <button class="button" type="button" title="Set Image">
- <img src="/base/static/src/img/icons/STOCK_DIRECTORY.png"/>
- </button>
- <input type="file" class="oe-binary-file" name="ufile"/>
- </form>
- </div>
- </td>
- <td>
- <button class="button oe-binary-file-clear" type="button" title="Clear">
- <img src="/base/static/src/img/icons/STOCK_MISSING_IMAGE.png"/>
- </button>
- </td>
- </tr>
- </table>
- </div>
- <div class="oe-binary-progress" style="display: none">
- <img src="/base/static/src/img/throbber.gif" width="16" height="16"/>
- <b>Uploading ...</b>
- </div>
- <iframe t-att-id="widget.iframe" t-att-name="widget.iframe" style="display: none"> </iframe>
- </td>
- </tr>
- </table>
-</t>
-<t t-name="FieldBinaryFile">
- <table cellpadding="0" cellspacing="0" border="0" width="100%">
- <tr>
- <td width="100%">
- <input type="text" size="1"
- t-att-name="widget.name"
- t-att-id="widget.element_id + '_field'"
- t-att-class="'field_' + widget.type" style="width: 100%"
- />
- </td>
- <td class="oe-binary" nowrap="true">
- <table cellspacing="0" cellpadding="0" border="0">
- <tr>
- <td>
- <div class="oe-binary-file-set" style="width: 80px; height:22px;">
- <form class="oe-binary-form" t-att-target="widget.iframe"
- method="post" enctype="multipart/form-data" action="/base/binary/upload">
- <input type="hidden" name="session_id" value=""/>
- <input type="hidden" name="callback" t-att-value="widget.iframe"/>
- <button class="button" type="button" title="Set Image">
- <img src="/base/static/src/img/icons/STOCK_DIRECTORY.png"/>
- <span>Select</span>
- </button>
- <input type="file" class="oe-binary-file" name="ufile"/>
- </form>
- </div>
- </td>
- <td>
- <button class="button oe-binary-file-save" type="button" title="Save As">
- <img src="/base/static/src/img/icons/gtk-save.png"/>
- <span>Save As</span>
- </button>
- </td>
- <td>
- <button class="button oe-binary-file-clear" type="button" title="Clear">
- <img src="/base/static/src/img/icons/STOCK_MISSING_IMAGE.png"/>
- <span>Clear</span>
- </button>
- </td>
- </tr>
- </table>
- </td>
- <td class="oe-binary-progress" style="display: none" nowrap="true">
- <img src="/base/static/src/img/throbber.gif" width="16" height="16"/>
- <b>Uploading ...</b>
- <iframe t-att-id="widget.iframe" t-att-name="widget.iframe" style="display: none"> </iframe>
- </td>
- </tr>
- </table>
-</t>
-<t t-name="WidgetButton">
- <button type="button"
- t-att-id="widget.element_id + '_button'"
- t-att-title="widget.help"
- style="width: 100%" class="button">
- <img t-if="widget.node.attrs.icon" t-att-src="'/base/static/src/img/icons/' + widget.node.attrs.icon + '.png'" width="16" height="16"/>
- <span t-if="widget.string"><t t-esc="widget.string"/></span>
- </button>
-</t>
-<t t-name="SearchView">
- <h2 class="oe_view_title"><t t-esc="view.attrs['string']"/></h2>
- <form class="oe_forms">
- <t t-call="SearchView.render_lines"/>
- <div class="oe_search-view-buttons" style="text-align: right;">
- <input type="submit" value="Search"/>
- <input type="reset" value="Clear"/>
- <button class="oe_search-view-custom-filter-btn"><span>Advanced Filter</span></button>
- <select class="oe_search-view-filters-management">
- </select>
- </div>
- </form>
-</t>
-<t t-name="SearchView.managed-filters">
- <option value="_filters">-- Filters --</option>
- <t t-set="i" t-value="0"/>
- <t t-foreach="filters" t-as="filter">
- <option t-att-value="'get:' + i"><t t-esc="filter.name"/></option>
- <t t-set="i" t-value="i+1"/>
- </t>
- <option value="_actions">-- Actions --</option>
- <option value="save_filter">Save Filter</option>
- <option value="manage_filters">Manage Filters</option>
-</t>
-<t t-name="SearchView.managed-filters.add">
- <div>
- <p>Filter Name:</p>
- <input type="text"/>
- <p>(Any existing filter with the same name will be replaced)</p>
- </div>
-</t>
-<t t-name="SearchView.render_lines">
- <table class="oe-searchview-render-line" border="0" cellspacing="0" cellpadding="0"
- t-foreach="lines" t-as="line">
- <tr>
- <td t-foreach="line" t-as="widget">
- <t t-raw="widget.render(defaults)"/>
- </td>
- </tr>
- </table>
-</t>
-<button t-name="SearchView.filter" type="button"
- t-att-id="element_id"
- t-att-title="attrs.help"
- t-att-class="classes.join(' ')"
- t-att-autofocus="attrs.default_focus === '1' ? 'autofocus' : undefined">
- <img t-if="attrs.icon" t-att-src="'/base/static/src/img/icons/' + attrs.icon + '.png'" width="16" height="16"/>
- <br t-if="attrs.icon and attrs.string"/>
- <t t-esc="attrs.string"/>
-</button>
-<span t-name="SearchView.filters" class="filter_label_group"
- ><t t-foreach="filters" t-as="filter"
- ><t t-raw="filter.render(defaults)"/></t
-></span>
-<t t-name="SearchView.field">
- <label t-att-class="'oe_label' + (attrs.help ? '_help' : '')"
- t-att-title="attrs.help"
- t-att-for="element_id">
- <t t-esc="attrs.string || attrs.name"/>
- <span t-if="attrs.help">?</span>
- </label>
- <div style="white-space: nowrap;">
- <input type="text" size="15" t-att-name="attrs.name"
- t-att-autofocus="attrs.default_focus === '1' ? 'autofocus' : undefined"
- t-att-id="element_id"
- t-att-value="defaults[attrs.name] || ''"/>
- <t t-if="filters.length" t-raw="filters.render(defaults)"/>
- </div>
-</t>
-<t t-name="SearchView.field.selection">
- <label t-att-title="attrs.help"
- t-att-class="'oe_label' + (attrs.help ? '_help' : '')"
- t-att-for="element_id">
- <t t-esc="attrs.string || attrs.name"/>
- <span t-if="attrs.help">?</span>
- </label>
- <div style="white-space: nowrap;">
- <select t-att-name="attrs.name" t-att-id="element_id"
- t-att-autofocus="attrs.default_focus === '1' || undefined">
- <option/>
- <t t-foreach="attrs.selection" t-as="option">
- <t t-set="selected" t-value="defaults[attrs.name] === option[0]"/>
- <option t-if="selected"
- t-att-value="option[0]" selected="selected">
- <t t-esc="option[1]"/>
- </option>
- <option t-if="!selected" t-att-value="option[0]">
- <t t-esc="option[1]"/>
- </option>
- </t>
- </select>
- <t t-if="filters.length" t-raw="filters.render(defaults)"/>
- </div>
-</t>
-<t t-name="SearchView.util.expand">
- <div t-att-class="'searchview_group ' + (expand == '0' ? 'folded' : 'expanded')"
- t-att-id="element_id">
- <a t-if="label" class="searchview_group_string" href="#">
- <t t-esc="label"/>
- </a>
- <div class="searchview_group_content">
- <t t-raw="content"/>
- </div>
- </div>
-</t>
-<t t-name="SearchView.group">
- <t t-call="SearchView.util.expand">
- <t t-set="expand" t-value="attrs.expand"/>
- <t t-set="label" t-value="attrs.string"/>
- <t t-set="content">
- <t t-call="SearchView.render_lines"/>
- </t>
- </t>
-</t>
-<t t-name="SearchView.extended_search">
- <t t-call="SearchView.util.expand">
- <t t-set="expand" t-value="false"/>
- <t t-set="label" t-value="'Advanced Filters'"/>
- <t t-set="content">
- <div class="searchview_extended_groups_list">
- </div>
- </t>
- </t>
-</t>
-<t t-name="SearchView.extended_search.group">
- <div t-att-id="element_id" class="searchview_extended_group">
- <select class="searchview_extended_group_choice">
- <option value="any">Any of the following conditions must match</option>
- <option value="all">All the following conditions must match</option>
- <option value="none">None of the following conditions must match</option>
- </select>
- <a class="searchview_extended_delete_group"
- href="javascript:void(0)"><span></span></a>
- <div class="searchview_extended_propositions_list">
- </div>
- <a class="searchview_extended_add_proposition" href="javascript:void(0)">
- <span>Add condition</span></a>
- <div class="oe_adv_filters_and"><span>and</span></div>
- </div>
-</t>
-<t t-name="SearchView.extended_search.proposition">
- <div t-att-id="element_id">
- <select class="searchview_extended_prop_field">
- <t t-foreach="attrs.fields" t-as="field">
- <option t-att="{'selected': field === attrs.selected ? 'selected' : null}"
- t-att-value="field.name">
- <t t-esc="field.string"/>
- </option>
- </t>
- </select>
- <select class="searchview_extended_prop_op"/>
- <span class="searchview_extended_prop_value"/>
- <a class="searchview_extended_delete_prop"
- href="javascript:void(0)"><span> </span></a>
- </div>
-</t>
-<t t-name="SearchView.extended_search.proposition.char">
- <input t-att-id="element_id" class="field_char"/>
-</t>
-<t t-name="SearchView.extended_search.proposition.datetime">
- <input t-att-id="element_id" class="field_datetime"/>
-</t>
-<t t-name="SearchView.extended_search.proposition.date">
- <input t-att-id="element_id" class="field_date"/>
-</t>
-<t t-name="SearchView.extended_search.proposition.integer">
- <input type="number" t-att-id="element_id" class="field_integer" step="1"/>
-</t>
-<t t-name="SearchView.extended_search.proposition.float">
- <input type="number" t-att-id="element_id" class="field_float" step="0.01"/>
-</t>
-<t t-name="SearchView.extended_search.proposition.boolean">
-</t>
-<t t-name="SearchView.extended_search.proposition.selection">
- <select t-att-id="element_id">
- <t t-foreach="field.selection" t-as="element">
- <option t-att-value="element[0]"><t t-esc="element[1]"/></option>
- </t>
- </select>
-</t>
-<t t-name="DialogWarning">
- <table cellspacing="0" cellpadding="0" border="0" class="oe-dialog-warning">
- <tr>
- <td><img src="/base/static/src/img/warning.png" class="oe-dialog-icon"/></td>
- <td>
- <p>
- <t t-js="d">
- var message = d.message ? d.message : d.error.data.fault_code;
- d.html_error = context.engine.tools.html_escape(message)
- .replace(/\n/g, '<br/>');
- </t>
- <t t-raw="html_error"/>
- </p>
- </td>
- </tr>
- </table>
-</t>
-<t t-name="DialogTraceback">
- <pre><t t-esc="error.message"/></pre>
- <hr/>
- <pre><t t-esc="error.data.debug"/></pre>
-</t>
-<t t-name="SelectCreatePopup">
- <div t-att-id="element_id">
- <table style="width:100%">
- <tr style="width:100%">
- <td style="width:100%">
- <div t-att-id="element_id + '_search'" style="width:100%"></div>
- </td>
- </tr>
- <tr style="width:100%">
- <td style="width:100%">
- <div t-att-id="element_id + '_view_list'" style="width:100%"></div>
- </td>
- </tr>
- </table>
- <div t-att-id="element_id + '_view_form'" style="width:100%"></div>
- </div>
-</t>
-<t t-name="SelectCreatePopup.search.buttons">
- <button type="button" class="oe_selectcreatepopup-search-select" disabled="disabled">Select</button>
- <button type="button" class="oe_selectcreatepopup-search-close">Cancel</button>
-</t>
-<t t-name="SelectCreatePopup.form.buttons">
- <t t-if="widget.options.disable_multiple_selection">
- <button type="button" class="oe_selectcreatepopup-form-save">Save</button>
- </t>
- <t t-if="! widget.options.disable_multiple_selection">
- <button type="button" class="oe_selectcreatepopup-form-save-new">Save &amp; New</button>
- <button type="button" class="oe_selectcreatepopup-form-save">Save &amp; Close</button>
- </t>
- <button type="button" class="oe_selectcreatepopup-form-close">Cancel</button>
-</t>
-<t t-name="FormOpenPopup">
- <div t-att-id="element_id">
- <div t-att-id="element_id + '_view_form'" style="width:100%"></div>
- </div>
-</t>
-<t t-name="FormOpenPopup.form.buttons">
- <button type="button" class="oe_formopenpopup-form-save">Save</button>
- <button type="button" class="oe_formopenpopup-form-close">Cancel</button>
-</t>
-<t t-name="ListView.row.frame" t-extend="WidgetFrame">
- <t t-jquery="tr">
- $(document.createElement('t'))
- .append(this.contents())
- .attr({
- 't-foreach': this.attr('t-foreach'),
- 't-as': this.attr('t-as')
- })
- .replaceAll(this)
- .after($(document.createElement('td')).append(
- $(document.createElement('button')).attr({
- 'class': 'oe-edit-row-save', 'type': 'button'}).text('Save')))
- .before($(document.createElement('td')).append(
- $(document.createElement('button')).attr({
- 'class': 'oe-edit-row-cancel', 'type': 'button'}).text('Cancel')))
- .unwrap();
- </t>
-</t>
-
-<t t-name="ExportView">
- <a id="exportview" href="javascript: void(0)" style="text-decoration: none;color: #3D3D3D;">Export</a>
-</t>
-<t t-name="ExportTreeView">
- <table class="view" style="background-color: #F3F3F3;">
- <tr>
- <td align="left">
- This wizard will export all data that matches the current search criteria to a CSV file.
- You can export all data or only the fields that can be reimported after modification.
- </td>
- </tr>
- <tr>
- <td>
- <table>
- <tr>
- <td class="label"><label>Export Type:</label></td>
- <td>
- <select id="import_compat" name="import_compat">
- <option value="1">Import Compatible Export</option>
- <option value="0">Export all Data</option>
- </select>
- </td>
- <td class="label"><label>Export Format</label></td>
- <td>
- <select id="export_format" name="export_format">
- <option value="csv">CSV</option>
- <option value="xls">Excel</option>
- </select>
- </td>
-
- </tr>
- </table>
- </td>
- </tr>
-
- <tr>
- <td>
- <table class="oe_export_fields_selector_export">
- <tr>
- <th class="oe_view_title" valign="bottom">Available fields</th>
- <th class="oe_view_title"></th>
- <th class="oe_view_title">Fields to export
- <a style="color: blue; text-decoration: none;" href="#" id="export_new_list">Save fields list</a>
- <div id="savenewlist"></div>
- <div id="ExistsExportList"></div>
- </th>
- </tr>
- <tr>
- <td class="oe_export_fields_selector_left">
- <div id="left_field_panel">
- </div>
- </td>
- <td>
- <table class="oe_export_fields_selector_center">
- <tr>
- <td align="center">
- <button id="add_field" class="oe_export_button_export">Add</button>
- </td>
- </tr>
- <tr>
- <td align="center">
- <button id="remove_field" class="oe_export_button_export">Remove</button>
- </td>
- </tr>
- <tr>
- <td align="center">
- <button id="remove_all_field" class="oe_export_button_export">Remove All</button>
- </td>
- </tr>
- </table>
- </td>
- <td class="oe_export_fields_selector_right">
- <select name="fields_list" id="fields_list" multiple="multiple"></select>
- </td>
- </tr>
- </table>
- </td>
- </tr>
- </table>
-</t>
-
-<t t-name="ExportTreeView-Secondary">
- <table id="field-tree-structure" class="oe_export_fields_selector_export" cellspacing="0" cellpadding="0">
- <tr><th class="oe_export_tree_header"> Name </th></tr>
- <t t-call="ExportTreeView-Secondary.children"/>
- </table>
-</t>
-<t t-name="ExportTreeView-Secondary.children">
- <t t-foreach="fields" t-as="field" >
- <tr t-att-id="'treerow-' + field.id" class="oe_export_row">
- <td>
- <table class="tree_grid" border="0">
- <tr class="oe_export_row">
- <t t-foreach="(field.id).split('/')" t-as="level" >
- <t t-if="(field.id).split('/')[0] != level">
- <td width="18">&amp;nbsp;</td>
- </t>
- </t>
- <td valign="top" align="left" style="cursor: pointer;" width="18">
- <t t-if="(field.children).length >= 1">
- <t t-if="(field.id).split('/').length != 3">
- <img t-att-id="'parentimg-' + field.id" src="/base/static/src/img/expand.gif" width="16" height="16" border="0"/>
- </t>
- </t>
- </td>
- <td id="tree-column" valign="middle" align="left" style="cursor: pointer;">
- <a t-att-id="'export-' + field.id" t-att-string="field.string" href="javascript: void(0);" style="text-decoration: none;">
- <t t-esc="field.string"/>
- </a>
- </td>
- </tr>
- </table>
- </td>
- </tr>
- </t>
-</t>
-
-<t t-name="ExportNewList">
- <tr>
- <th><label>Save as:</label></th>
- <td><input size="10" type="text" id="savelist_name"/></td>
- <td><button class="oe_export_button_export" id="add_export_list">Ok</button></td>
- </tr>
-</t>
-
-<t t-name="Exists.ExportList">
- <tr><th align="right"><label >Saved exports:</label></th></tr>
- <tr align="left">
- <td>
- <select id="saved_export_list" style="width: 100%;">
- <option></option>
- <t t-foreach="existing_exports" t-as="export">
- <option t-att-value="export.id"><t t-esc="export.name"/></option>
- </t>
- </select>
- </td>
- <td><button class="oe_export_button_export" id="delete_export_list">Delete</button></td>
- </tr>
-</t>
-<t t-name="Change_Pwd">
- <form name="change_password_form" class="oe_forms" method="POST">
- <table align="center">
- <tr>
- <td><label for="old_pwd">Old Password:</label></td>
- <td><input type="password" name="old_pwd"
- minlength="1" autofocus="autofocus"/></td>
- </tr>
- <tr>
- <td><label for="new_password">New Password:</label></td>
- <td><input type="password" name="new_password"
- minlength="1" autofocus="autofocus"/></td>
- </tr>
- <tr>
- <td><label for="confirm_pwd">Confirm Password:</label></td>
- <td><input type="password" name="confirm_pwd"
- minlength="1"/></td>
- </tr>
- <tr>
- <td colspan="2" align="right"><input type="submit" value="Change Password"/></td>
- </tr>
- </table>
- </form>
-</t>
-</templates>