From 3e68fd5a3e238954b5ac8aaa3354cb5f16e93169 Mon Sep 17 00:00:00 2001 From: YuCheng Hu Date: Sat, 19 Jun 2010 00:30:55 +0000 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=AF=AD=E8=A8=80=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +YUCHENG HU+ git-svn-id: https://svn.code.sf.net/p/hawebs/svn@365 a2543c7e-f6e9-4f8a-8bff-1ffc34733512 --- .../Releases/vTiger_zh_cn_5.1_20100618.zip | Bin 0 -> 155768 bytes .../%%47^47F^47FECAC7%%AddPickList.tpl.php | 86 ++ .../%%AB^AB0^AB08D088%%ShowRoleSelect.tpl.php | 13 + .../cache/513d62bd4346d3dc095da948ef81b9a1 | 136 +- .../trunk/include/database/PearDatabase.php | 1148 +++++++++++++++++ .../trunk/include/database/Postgres8.php | 228 ++++ .../include/db_backup/DatabaseBackup.php | 317 +++++ oss/vtiger/trunk/include/db_backup/backup.php | 351 +++++ oss/vtiger/trunk/include/db_backup/ftp.php | 65 + .../include/events/SqlResultIterator.inc | 92 ++ .../trunk/include/events/VTEntityData.inc | 125 ++ .../trunk/include/events/VTEntityType.inc | 87 ++ .../trunk/include/events/VTEventCondition.php | 82 ++ .../events/VTEventConditionParserLexer.php | 729 +++++++++++ .../events/VTEventConditionParserParser.php | 354 +++++ .../include/events/VTEventConditionSymbol.php | 16 + .../trunk/include/events/VTEventHandler.inc | 14 + .../trunk/include/events/VTEventTrigger.inc | 125 ++ .../trunk/include/events/VTEventsManager.inc | 189 +++ .../trunk/include/events/VTWSEntityType.inc | 203 +++ oss/vtiger/trunk/include/events/include.inc | 21 + .../fckeditor/editor/css/behaviors/anchor.gif | Bin 0 -> 184 bytes .../editor/css/behaviors/anchors.htc | 30 + .../editor/css/behaviors/disablehandles.htc | 15 + .../editor/css/behaviors/hiddenfield.gif | Bin 0 -> 111 bytes .../editor/css/behaviors/hiddenfield.htc | 30 + .../editor/css/behaviors/moz-bindings.xml | 59 + .../editor/css/behaviors/showtableborders.htc | 36 + .../fckeditor/editor/css/fck_editorarea.css | 67 + .../fckeditor/editor/css/fck_internal.css | 80 ++ .../editor/css/fck_showtableborders_gecko.css | 31 + .../dialog/common/fck_dialog_common.css | 79 ++ .../editor/dialog/common/fck_dialog_common.js | 125 ++ .../editor/dialog/common/fcknumericfield.htc | 24 + .../editor/dialog/common/images/locked.gif | Bin 0 -> 74 bytes .../editor/dialog/common/images/reset.gif | Bin 0 -> 104 bytes .../editor/dialog/common/images/unlocked.gif | Bin 0 -> 75 bytes .../editor/dialog/common/moz-bindings.xml | 28 + .../fckeditor/editor/dialog/fck_about.html | 144 +++ .../editor/dialog/fck_about/lgpl.html | 434 +++++++ .../dialog/fck_about/logo_fckeditor.gif | Bin 0 -> 2044 bytes .../editor/dialog/fck_about/logo_fredck.gif | Bin 0 -> 920 bytes .../fckeditor/editor/dialog/fck_anchor.html | 98 ++ .../fckeditor/editor/dialog/fck_button.html | 103 ++ .../fckeditor/editor/dialog/fck_checkbox.html | 103 ++ .../editor/dialog/fck_colorselector.html | 167 +++ .../fckeditor/editor/dialog/fck_docprops.html | 570 ++++++++ .../fck_docprops/fck_document_preview.html | 109 ++ .../fckeditor/editor/dialog/fck_find.html | 165 +++ .../fckeditor/editor/dialog/fck_flash.html | 142 ++ .../fckeditor/editor/dialog/fck_form.html | 101 ++ .../editor/dialog/fck_hiddenfield.html | 91 ++ .../fckeditor/editor/dialog/fck_image.html | 225 ++++ .../editor/dialog/fck_image/fck_image.js | 475 +++++++ .../dialog/fck_image/fck_image_preview.html | 61 + .../fckeditor/editor/dialog/fck_link.html | 289 +++++ .../editor/dialog/fck_link/fck_link.js | 588 +++++++++ .../fckeditor/editor/dialog/fck_listprop.html | 101 ++ .../fckeditor/editor/dialog/fck_paste.html | 217 ++++ .../editor/dialog/fck_radiobutton.html | 103 ++ .../fckeditor/editor/dialog/fck_replace.html | 131 ++ .../fckeditor/editor/dialog/fck_select.html | 172 +++ .../editor/dialog/fck_select/fck_select.js | 165 +++ .../fckeditor/editor/dialog/fck_smiley.html | 91 ++ .../fckeditor/editor/dialog/fck_source.html | 61 + .../editor/dialog/fck_specialchar.html | 109 ++ .../editor/dialog/fck_spellerpages.html | 59 + .../fck_spellerpages/spellerpages/blank.html | 0 .../spellerpages/controlWindow.js | 87 ++ .../spellerpages/controls.html | 153 +++ .../server-scripts/spellchecker.cfm | 132 ++ .../server-scripts/spellchecker.php | 193 +++ .../server-scripts/spellchecker.pl | 180 +++ .../spellerpages/spellChecker.js | 458 +++++++ .../spellerpages/spellchecker.html | 71 + .../spellerpages/spellerStyle.css | 49 + .../spellerpages/wordWindow.js | 271 ++++ .../fckeditor/editor/dialog/fck_table.html | 282 ++++ .../editor/dialog/fck_tablecell.html | 217 ++++ .../fckeditor/editor/dialog/fck_template.html | 210 +++ .../fckeditor/editor/dialog/fck_textarea.html | 90 ++ .../editor/dialog/fck_textfield.html | 131 ++ .../editor/dialog/fck_universalkey.html | 63 + .../editor/dialog/fck_universalkey/00.gif | Bin 0 -> 43 bytes .../editor/dialog/fck_universalkey/data.js | 70 + .../dialog/fck_universalkey/diacritic.js | 65 + .../dialog/fck_universalkey/dialogue.js | 31 + .../fck_universalkey/fck_universalkey.css | 62 + .../fck_universalkey/keyboard_layout.gif | Bin 0 -> 3056 bytes .../dialog/fck_universalkey/multihexa.js | 309 +++++ .../filemanager/browser/default/browser.css | 84 ++ .../filemanager/browser/default/browser.html | 148 +++ .../default/connectors/asp/basexml.asp | 58 + .../default/connectors/asp/class_upload.asp | 230 ++++ .../default/connectors/asp/commands.asp | 179 +++ .../browser/default/connectors/asp/config.asp | 45 + .../default/connectors/asp/connector.asp | 119 ++ .../browser/default/connectors/asp/io.asp | 85 ++ .../browser/default/connectors/asp/util.asp | 51 + .../default/connectors/aspx/connector.aspx | 26 + .../browser/default/connectors/cfm/config.cfm | 80 ++ .../default/connectors/cfm/connector.cfm | 364 ++++++ .../default/connectors/perl/basexml.pl | 59 + .../default/connectors/perl/commands.pl | 154 +++ .../default/connectors/perl/connector.cgi | 134 ++ .../browser/default/connectors/perl/io.pl | 127 ++ .../default/connectors/perl/upload_fck.pl | 663 ++++++++++ .../browser/default/connectors/perl/util.pl | 56 + .../default/connectors/php/basexml.php | 68 + .../default/connectors/php/commands.php | 211 +++ .../browser/default/connectors/php/config.php | 47 + .../default/connectors/php/connector.php | 107 ++ .../browser/default/connectors/php/io.php | 97 ++ .../browser/default/connectors/php/util.php | 37 + .../browser/default/connectors/test.html | 168 +++ .../browser/default/frmactualfolder.html | 63 + .../browser/default/frmcreatefolder.html | 109 ++ .../browser/default/frmfolders.html | 192 +++ .../browser/default/frmresourceslist.html | 152 +++ .../browser/default/frmresourcetype.html | 61 + .../browser/default/frmupload.html | 109 ++ .../browser/default/images/ButtonArrow.gif | Bin 0 -> 138 bytes .../browser/default/images/Folder.gif | Bin 0 -> 128 bytes .../browser/default/images/Folder32.gif | Bin 0 -> 281 bytes .../browser/default/images/FolderOpened.gif | Bin 0 -> 132 bytes .../browser/default/images/FolderOpened32.gif | Bin 0 -> 264 bytes .../browser/default/images/FolderUp.gif | Bin 0 -> 132 bytes .../browser/default/images/icons/32/ai.gif | Bin 0 -> 1140 bytes .../browser/default/images/icons/32/avi.gif | Bin 0 -> 454 bytes .../browser/default/images/icons/32/bmp.gif | Bin 0 -> 709 bytes .../browser/default/images/icons/32/cs.gif | Bin 0 -> 224 bytes .../default/images/icons/32/default.icon.gif | Bin 0 -> 177 bytes .../browser/default/images/icons/32/dll.gif | Bin 0 -> 258 bytes .../browser/default/images/icons/32/doc.gif | Bin 0 -> 260 bytes .../browser/default/images/icons/32/exe.gif | Bin 0 -> 170 bytes .../browser/default/images/icons/32/fla.gif | Bin 0 -> 946 bytes .../browser/default/images/icons/32/gif.gif | Bin 0 -> 704 bytes .../browser/default/images/icons/32/htm.gif | Bin 0 -> 1527 bytes .../browser/default/images/icons/32/html.gif | Bin 0 -> 1527 bytes .../browser/default/images/icons/32/jpg.gif | Bin 0 -> 463 bytes .../browser/default/images/icons/32/js.gif | Bin 0 -> 274 bytes .../browser/default/images/icons/32/mdb.gif | Bin 0 -> 274 bytes .../browser/default/images/icons/32/mp3.gif | Bin 0 -> 454 bytes .../browser/default/images/icons/32/pdf.gif | Bin 0 -> 567 bytes .../browser/default/images/icons/32/ppt.gif | Bin 0 -> 254 bytes .../browser/default/images/icons/32/rdp.gif | Bin 0 -> 1493 bytes .../browser/default/images/icons/32/swf.gif | Bin 0 -> 725 bytes .../browser/default/images/icons/32/swt.gif | Bin 0 -> 724 bytes .../browser/default/images/icons/32/txt.gif | Bin 0 -> 213 bytes .../browser/default/images/icons/32/vsd.gif | Bin 0 -> 277 bytes .../browser/default/images/icons/32/xls.gif | Bin 0 -> 271 bytes .../browser/default/images/icons/32/xml.gif | Bin 0 -> 408 bytes .../browser/default/images/icons/32/zip.gif | Bin 0 -> 368 bytes .../browser/default/images/icons/ai.gif | Bin 0 -> 403 bytes .../browser/default/images/icons/avi.gif | Bin 0 -> 249 bytes .../browser/default/images/icons/bmp.gif | Bin 0 -> 126 bytes .../browser/default/images/icons/cs.gif | Bin 0 -> 128 bytes .../default/images/icons/default.icon.gif | Bin 0 -> 113 bytes .../browser/default/images/icons/dll.gif | Bin 0 -> 132 bytes .../browser/default/images/icons/doc.gif | Bin 0 -> 140 bytes .../browser/default/images/icons/exe.gif | Bin 0 -> 109 bytes .../browser/default/images/icons/fla.gif | Bin 0 -> 382 bytes .../browser/default/images/icons/gif.gif | Bin 0 -> 125 bytes .../browser/default/images/icons/htm.gif | Bin 0 -> 621 bytes .../browser/default/images/icons/html.gif | Bin 0 -> 621 bytes .../browser/default/images/icons/jpg.gif | Bin 0 -> 125 bytes .../browser/default/images/icons/js.gif | Bin 0 -> 139 bytes .../browser/default/images/icons/mdb.gif | Bin 0 -> 146 bytes .../browser/default/images/icons/mp3.gif | Bin 0 -> 249 bytes .../browser/default/images/icons/pdf.gif | Bin 0 -> 230 bytes .../browser/default/images/icons/ppt.gif | Bin 0 -> 139 bytes .../browser/default/images/icons/rdp.gif | Bin 0 -> 606 bytes .../browser/default/images/icons/swf.gif | Bin 0 -> 388 bytes .../browser/default/images/icons/swt.gif | Bin 0 -> 388 bytes .../browser/default/images/icons/txt.gif | Bin 0 -> 122 bytes .../browser/default/images/icons/vsd.gif | Bin 0 -> 136 bytes .../browser/default/images/icons/xls.gif | Bin 0 -> 138 bytes .../browser/default/images/icons/xml.gif | Bin 0 -> 231 bytes .../browser/default/images/icons/zip.gif | Bin 0 -> 235 bytes .../browser/default/images/spacer.gif | Bin 0 -> 43 bytes .../filemanager/browser/default/js/common.js | 34 + .../filemanager/browser/default/js/fckxml.js | 109 ++ oss/vtiger/trunk/include/fpdf/pdfconfig.php | 2 +- .../trunk/include/language/zh_cn.lang.php | 1 + .../modules/PickList/language/zh_cn.lang.php | 65 +- .../modules/Settings/language/zh_cn.lang.php | 6 +- 186 files changed, 17398 insertions(+), 85 deletions(-) create mode 100644 oss/vtiger/trunk/Releases/vTiger_zh_cn_5.1_20100618.zip create mode 100644 oss/vtiger/trunk/Smarty/templates_c/%%47^47F^47FECAC7%%AddPickList.tpl.php create mode 100644 oss/vtiger/trunk/Smarty/templates_c/%%AB^AB0^AB08D088%%ShowRoleSelect.tpl.php create mode 100644 oss/vtiger/trunk/include/database/PearDatabase.php create mode 100644 oss/vtiger/trunk/include/database/Postgres8.php create mode 100644 oss/vtiger/trunk/include/db_backup/DatabaseBackup.php create mode 100644 oss/vtiger/trunk/include/db_backup/backup.php create mode 100644 oss/vtiger/trunk/include/db_backup/ftp.php create mode 100644 oss/vtiger/trunk/include/events/SqlResultIterator.inc create mode 100644 oss/vtiger/trunk/include/events/VTEntityData.inc create mode 100644 oss/vtiger/trunk/include/events/VTEntityType.inc create mode 100644 oss/vtiger/trunk/include/events/VTEventCondition.php create mode 100644 oss/vtiger/trunk/include/events/VTEventConditionParserLexer.php create mode 100644 oss/vtiger/trunk/include/events/VTEventConditionParserParser.php create mode 100644 oss/vtiger/trunk/include/events/VTEventConditionSymbol.php create mode 100644 oss/vtiger/trunk/include/events/VTEventHandler.inc create mode 100644 oss/vtiger/trunk/include/events/VTEventTrigger.inc create mode 100644 oss/vtiger/trunk/include/events/VTEventsManager.inc create mode 100644 oss/vtiger/trunk/include/events/VTWSEntityType.inc create mode 100644 oss/vtiger/trunk/include/events/include.inc create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/anchor.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/anchors.htc create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/disablehandles.htc create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/hiddenfield.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/hiddenfield.htc create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/moz-bindings.xml create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/showtableborders.htc create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/css/fck_editorarea.css create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/css/fck_internal.css create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/css/fck_showtableborders_gecko.css create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/common/fck_dialog_common.css create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/common/fck_dialog_common.js create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/common/fcknumericfield.htc create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/common/images/locked.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/common/images/reset.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/common/images/unlocked.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/common/moz-bindings.xml create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_about.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_about/lgpl.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_about/logo_fckeditor.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_about/logo_fredck.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_anchor.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_button.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_checkbox.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_colorselector.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_docprops.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_docprops/fck_document_preview.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_find.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_flash.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_form.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_hiddenfield.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_image.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_image/fck_image.js create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_image/fck_image_preview.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_link.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_link/fck_link.js create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_listprop.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_paste.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_radiobutton.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_replace.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_select.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_select/fck_select.js create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_smiley.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_source.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_specialchar.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/blank.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controlWindow.js create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controls.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.cfm create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.pl create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellChecker.js create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellchecker.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellerStyle.css create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/wordWindow.js create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_table.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_tablecell.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_template.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_textarea.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_textfield.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/00.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/data.js create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/diacritic.js create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/dialogue.js create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/fck_universalkey.css create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/keyboard_layout.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/multihexa.js create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/browser.css create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/browser.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/basexml.asp create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/class_upload.asp create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/commands.asp create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/config.asp create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/connector.asp create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/io.asp create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/util.asp create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/cfm/config.cfm create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/cfm/connector.cfm create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/basexml.pl create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/commands.pl create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/connector.cgi create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/io.pl create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/upload_fck.pl create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/util.pl create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/basexml.php create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/commands.php create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/config.php create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/io.php create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/util.php create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/test.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmactualfolder.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmcreatefolder.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmfolders.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmresourceslist.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmresourcetype.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmupload.html create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/ButtonArrow.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/Folder.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/Folder32.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/FolderOpened.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/FolderOpened32.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/FolderUp.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/ai.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/avi.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/bmp.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/cs.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/default.icon.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/dll.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/doc.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/exe.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/fla.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/gif.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/htm.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/html.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/jpg.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/js.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/mdb.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/mp3.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/pdf.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/ppt.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/rdp.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/swf.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/swt.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/txt.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/vsd.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/xls.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/xml.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/zip.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/ai.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/avi.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/bmp.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/cs.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/default.icon.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/dll.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/doc.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/exe.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/fla.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/gif.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/htm.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/html.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/jpg.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/js.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/mdb.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/mp3.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/pdf.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/ppt.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/rdp.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/swf.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/swt.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/txt.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/vsd.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/xls.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/xml.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/zip.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/spacer.gif create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/js/common.js create mode 100644 oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/js/fckxml.js diff --git a/oss/vtiger/trunk/Releases/vTiger_zh_cn_5.1_20100618.zip b/oss/vtiger/trunk/Releases/vTiger_zh_cn_5.1_20100618.zip new file mode 100644 index 0000000000000000000000000000000000000000..490f9e284aca2dffd72aaaf0bda37c6b51591049 GIT binary patch literal 155768 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

OkF!-wQC4=xdN<#<}QOytF^|A9j3X( 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 literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/Smarty/templates_c/%%47^47F^47FECAC7%%AddPickList.tpl.php b/oss/vtiger/trunk/Smarty/templates_c/%%47^47F^47FECAC7%%AddPickList.tpl.php new file mode 100644 index 00000000..c46f6c5f --- /dev/null +++ b/oss/vtiger/trunk/Smarty/templates_c/%%47^47F^47FECAC7%%AddPickList.tpl.php @@ -0,0 +1,86 @@ + +

+ + + + +
_tpl_vars['MOD']['ADD_PICKLIST_VALUES']; ?> + - _tpl_vars['FIELDLABEL']; ?> +
+ + + + + + + + + + + + + +
+ _tpl_vars['MOD']['LBL_EXISTING_PICKLIST_VALUES']; ?> + +
+ + _tpl_vars['PICKVAL']; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array'); }if (count($_from)): + foreach ($_from as $this->_tpl_vars['pick_val']): +?> + + + + +
+ _tpl_vars['pick_val']; ?> + +
+
+
+ _tpl_vars['NONEDITPICKLIST'] )): ?> + _tpl_vars['MOD']['LBL_NON_EDITABLE_PICKLIST_ENTRIES']; ?> + : +
+ + _tpl_vars['NONEDITPICKLIST']; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array'); }if (count($_from)): + foreach ($_from as $this->_tpl_vars['nonedit']): +?> + + + + +
+ + _tpl_vars['nonedit']; ?> + + +
+
+ +
+ _tpl_vars['MOD']['LBL_PICKLIST_ADDINFO']; ?> + + +
+ _tpl_vars['MOD']['LBL_SELECT_ROLES']; ?> +
+ +
+ + +
+
\ No newline at end of file diff --git a/oss/vtiger/trunk/Smarty/templates_c/%%AB^AB0^AB08D088%%ShowRoleSelect.tpl.php b/oss/vtiger/trunk/Smarty/templates_c/%%AB^AB0^AB08D088%%ShowRoleSelect.tpl.php new file mode 100644 index 00000000..22205088 --- /dev/null +++ b/oss/vtiger/trunk/Smarty/templates_c/%%AB^AB0^AB08D088%%ShowRoleSelect.tpl.php @@ -0,0 +1,13 @@ + +_tpl_vars['MOD']['LBL_SELECT_ROLES']; ?> +
+ \ No newline at end of file diff --git a/oss/vtiger/trunk/cache/513d62bd4346d3dc095da948ef81b9a1 b/oss/vtiger/trunk/cache/513d62bd4346d3dc095da948ef81b9a1 index 5c3cbd18..fd23bd42 100644 --- a/oss/vtiger/trunk/cache/513d62bd4346d3dc095da948ef81b9a1 +++ b/oss/vtiger/trunk/cache/513d62bd4346d3dc095da948ef81b9a1 @@ -1,10 +1,68 @@ -O:9:"MagpieRSS":23:{s:6:"parser";i:0;s:12:"current_item";a:0:{}s:5:"items";a:20:{i:0;a:8:{s:5:"title";s:57:"如何添加“事件”中的选项才能正确显示?";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=794";s:11:"description";s:873:"我在下拉框编辑项的事件中,在电话、会议外添加“通知、备忘”等选项,但在客户中添加“通知”的相应内容时,在成功保存后却无法显示。但在事件还可以找到相应的内容,就是无法与客户相联系。只有修改电话或者会议后,才可以捆绑两者的联系并成功显示。 - 请问应该如何设 ... -


-

";s:8:"category";s:6:"Vtiger";s:6:"author";s:9:"southlion";s:7:"pubdate";s:31:"Thu, 17 Jun 2010 13:43:17 +0000";s:7:"summary";s:873:"我在下拉框编辑项的事件中,在电话、会议外添加“通知、备忘”等选项,但在客户中添加“通知”的相应内容时,在成功保存后却无法显示。但在事件还可以找到相应的内容,就是无法与客户相联系。只有修改电话或者会议后,才可以捆绑两者的联系并成功显示。 - 请问应该如何设 ... -


-

";s:14:"date_timestamp";i:1276782197;}i:1;a:8:{s:5:"title";s:21:"网页邮件不能用";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=786";s:11:"description";s:833:"VT有个网页邮件的功能,我点击的时候提示我: +O:9:"MagpieRSS":23:{s:6:"parser";i:0;s:12:"current_item";a:0:{}s:5:"items";a:20:{i:0;a:8:{s:5:"title";s:73:"有一个问题: 下拉框编辑的界面是乱码,我该怎么处理呢?";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=801";s:11:"description";s:765:"有一个问题: 下拉框编辑的界面是乱码,我该怎么处理呢? 我哪里弄错了? 如果修改,我怎么修改呢? 谢谢了! + +另外:下拉框编辑我怎么改动不成功呢?好像缺少按钮了! 我的系统缺少文件? + + +截图如下: + +1419[/attach] ... +


+

";s:8:"category";s:6:"Vtiger";s:6:"author";s:11:"davidyang99";s:7:"pubdate";s:31:"Fri, 18 Jun 2010 16:10:37 +0000";s:7:"summary";s:765:"有一个问题: 下拉框编辑的界面是乱码,我该怎么处理呢? 我哪里弄错了? 如果修改,我怎么修改呢? 谢谢了! + +另外:下拉框编辑我怎么改动不成功呢?好像缺少按钮了! 我的系统缺少文件? + + +截图如下: + +1419[/attach] ... +


+

";s:14:"date_timestamp";i:1276877437;}i:1;a:8:{s:5:"title";s:70:"求救: 这个问题怎么解决?文件管理无法浏览上传文件?";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=800";s:11:"description";s:684:"在"文件管理"下面,怎么把文件增加进去呢? 没有浏览菜单呀! 谁有类似的问题呀? 还是我哪里错了? 帮忙解决一下,谢谢! + +截图如下: +1418[/attach] +


+

";s:8:"category";s:6:"Vtiger";s:6:"author";s:11:"davidyang99";s:7:"pubdate";s:31:"Fri, 18 Jun 2010 15:58:26 +0000";s:7:"summary";s:684:"在"文件管理"下面,怎么把文件增加进去呢? 没有浏览菜单呀! 谁有类似的问题呀? 还是我哪里错了? 帮忙解决一下,谢谢! + +截图如下: +1418[/attach] +


+

";s:14:"date_timestamp";i:1276876706;}i:2;a:8:{s:5:"title";s:79:"大家有没有遇到过这样的问题。invoice生成pdf文件成这个样子";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=799";s:11:"description";s:830:"[i=s] 本帖最后由 tkboy 于 2010-6-18 20:04 编辑 [/i] + +1416[/attach] + + + + +在saleorder生成的pdf却没问题。六页每页6个产品。而在invoice生成第二页就不行了。而且还生成了五百多页 + + +1417[/attach] + +还有个情况就是在数量多的产品和产品描述很长的时候就会出现这个情况。12 ... +


+

";s:8:"category";s:6:"Vtiger";s:6:"author";s:5:"tkboy";s:7:"pubdate";s:31:"Fri, 18 Jun 2010 11:58:43 +0000";s:7:"summary";s:830:"[i=s] 本帖最后由 tkboy 于 2010-6-18 20:04 编辑 [/i] + +1416[/attach] + + + + +在saleorder生成的pdf却没问题。六页每页6个产品。而在invoice生成第二页就不行了。而且还生成了五百多页 + + +1417[/attach] + +还有个情况就是在数量多的产品和产品描述很长的时候就会出现这个情况。12 ... +


+

";s:14:"date_timestamp";i:1276862323;}i:3;a:8:{s:5:"title";s:57:"如何添加“事件”中的选项才能正确显示?";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=794";s:11:"description";s:875:"我在下拉框编辑项的事件中,在电话、会议外添加“通知、备忘”等选项,但在客户中添加“通知”的相应内容时,在成功保存后却无法显示。但在事件还可以找到相应的内容,就是无法与客户相联系。只有修改电话或者会议后,才可以捆绑两者的联系并成功显示。 + +请问应该如何设置添 ... +


+

";s:8:"category";s:6:"Vtiger";s:6:"author";s:9:"southlion";s:7:"pubdate";s:31:"Thu, 17 Jun 2010 13:43:17 +0000";s:7:"summary";s:875:"我在下拉框编辑项的事件中,在电话、会议外添加“通知、备忘”等选项,但在客户中添加“通知”的相应内容时,在成功保存后却无法显示。但在事件还可以找到相应的内容,就是无法与客户相联系。只有修改电话或者会议后,才可以捆绑两者的联系并成功显示。 + +请问应该如何设置添 ... +


+

";s:14:"date_timestamp";i:1276782197;}i:4;a:8:{s:5:"title";s:21:"网页邮件不能用";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=786";s:11:"description";s:833:"VT有个网页邮件的功能,我点击的时候提示我: 无法连接到邮件服务器。请检查邮件服务器的细节 这. 请 点击这里 电子邮件模块 [/b] @@ -26,7 +84,7 @@ http://forums.hawebs.net/computer/viewthread.php?tid=221&highli ... 之前看了这个帖子: http://forums.hawebs.net/computer/viewthread.php?tid=221&highli ...


-

";s:14:"date_timestamp";i:1276670948;}i:2;a:8:{s:5:"title";s:24:"导出数据乱码问题";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=767";s:11:"description";s:853:"[i=s] 本帖最后由 mydream 于 2010-6-12 19:21 编辑 [/i] +

";s:14:"date_timestamp";i:1276670948;}i:5;a:8:{s:5:"title";s:24:"导出数据乱码问题";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=767";s:11:"description";s:853:"[i=s] 本帖最后由 mydream 于 2010-6-12 19:21 编辑 [/i] 选择导出用户资料,都是乱码,我用数据库工具查看表中数据也是乱码。字符集编码我已经设置为utf-8了,这是为什么呢。。。。。 @@ -42,7 +100,7 @@ http://forums.hawebs.net/computer/viewthread.php?tid=221&highli ... 就是在导出客户信息或者其他数据的时候,到处成一个e ...


-

";s:14:"date_timestamp";i:1276332879;}i:3;a:8:{s:5:"title";s:53:"唉 纠结啊 vtiger生成的pdf文档还是有问题";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=766";s:11:"description";s:675:"vtiger V5.1版本还有 5.2版本生成的pdf文档中折扣和税款部分显示的数字不能超过3位 +

";s:14:"date_timestamp";i:1276332879;}i:6;a:8:{s:5:"title";s:53:"唉 纠结啊 vtiger生成的pdf文档还是有问题";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=766";s:11:"description";s:675:"vtiger V5.1版本还有 5.2版本生成的pdf文档中折扣和税款部分显示的数字不能超过3位 订单上的金额 1327[/attach] 生成pdf文档上面的金额 @@ -54,7 +112,7 @@ http://forums.hawebs.net/computer/viewthread.php?tid=221&highli ... 生成pdf文档上面的金额 1328[/attach]


-

";s:14:"date_timestamp";i:1276327521;}i:4;a:8:{s:5:"title";s:59:"请教vtiger V5.1备份数据库功能使用后如何还原";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=765";s:11:"description";s:750:"这几天玩vtiger 突然发现两个问题 +

";s:14:"date_timestamp";i:1276327521;}i:7;a:8:{s:5:"title";s:59:"请教vtiger V5.1备份数据库功能使用后如何还原";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=765";s:11:"description";s:750:"这几天玩vtiger 突然发现两个问题 1.vtiger V5.1里的备份数据库功能是否是备份所有的数据?(包含客户资料、自己上传的文件等) @@ -74,7 +132,7 @@ http://forums.hawebs.net/computer/viewthread.php?tid=221&highli ... 嘿嘿 ...


-

";s:14:"date_timestamp";i:1276306122;}i:5;a:8:{s:5:"title";s:70:"vTiger 运行时出现错误 Sorry! Attempt to access restricted file.";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=762";s:11:"description";s:660:"vTiger 运行时出现错误 +

";s:14:"date_timestamp";i:1276306122;}i:8;a:8:{s:5:"title";s:70:"vTiger 运行时出现错误 Sorry! Attempt to access restricted file.";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=762";s:11:"description";s:660:"vTiger 运行时出现错误 Sorry! Attempt to access restricted file. @@ -90,7 +148,7 @@ Sorry! Attempt to access restricted file. 这是因为 vTiger 的运行配置文件的文件绝对路径配置不正确。


-

";s:14:"date_timestamp";i:1276287837;}i:6;a:8:{s:5:"title";s:60:"解决Vtiger在导出PDF文件中文字符为乱码的方法";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=761";s:11:"description";s:846:"使用中发现Vtiger在导出PDF文件的时候,中文字符为乱码,按照网上介绍的方法,结合此版本,找到了解决的方法,此问题的主要原因在于tcpdf中对字符的引用问题,如果使用的是Vtiger5.1版本中自 +

";s:14:"date_timestamp";i:1276287837;}i:9;a:8:{s:5:"title";s:60:"解决Vtiger在导出PDF文件中文字符为乱码的方法";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=761";s:11:"description";s:846:"使用中发现Vtiger在导出PDF文件的时候,中文字符为乱码,按照网上介绍的方法,结合此版本,找到了解决的方法,此问题的主要原因在于tcpdf中对字符的引用问题,如果使用的是Vtiger5.1版本中自 带的tcpdf,仅需要修改include\tcpdf\tcpdf.php文件即可。将文件中2674行的 $fami ... @@ -100,7 +158,7 @@ $fami ... 带的tcpdf,仅需要修改include\tcpdf\tcpdf.php文件即可。将文件中2674行的 $fami ...


-

";s:14:"date_timestamp";i:1276264329;}i:7;a:8:{s:5:"title";s:32:"PBXManager 语言文件已发布";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=759";s:11:"description";s:803:"PBXManager 的中文语言文件已经发布到 SVN 服务器上了 +

";s:14:"date_timestamp";i:1276264329;}i:10;a:8:{s:5:"title";s:32:"PBXManager 语言文件已发布";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=759";s:11:"description";s:803:"PBXManager 的中文语言文件已经发布到 SVN 服务器上了 地址为 @@ -120,11 +178,11 @@ http://hawebs.svn.sourceforge.net/viewvc/hawebs/oss/vtiger/trunk/modules/PBXMana 在使用手机方式的时候,如果你是 ...


-

";s:14:"date_timestamp";i:1276197531;}i:8;a:8:{s:5:"title";s:15:"总算回来了";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=757";s:11:"description";s:506:"真不容易啊 +

";s:14:"date_timestamp";i:1276197531;}i:11;a:8:{s:5:"title";s:15:"总算回来了";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=757";s:11:"description";s:506:"真不容易啊


";s:8:"category";s:6:"Vtiger";s:6:"author";s:5:"qqing";s:7:"pubdate";s:31:"Thu, 10 Jun 2010 05:48:50 +0000";s:7:"summary";s:506:"真不容易啊


-

";s:14:"date_timestamp";i:1276148930;}i:9;a:8:{s:5:"title";s:66:"找到一个易客集成Discuz组件包望高手能整合到vtiger";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=756";s:11:"description";s:823:"不多说上附件 +

";s:14:"date_timestamp";i:1276148930;}i:12;a:8:{s:5:"title";s:66:"找到一个易客集成Discuz组件包望高手能整合到vtiger";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=756";s:11:"description";s:823:"不多说上附件 易客CRM集成Discuz5.0论坛的教程在引用里 易客CRM集成Discuz5.0论坛 安装步骤: @@ -144,7 +202,7 @@ http://hawebs.svn.sourceforge.net/viewvc/hawebs/oss/vtiger/trunk/modules/PBXMana 4)通过phpmyadmin导入bbs/discuz5.sql文件到CRM数据库中 ...


-

";s:14:"date_timestamp";i:1276136267;}i:10;a:8:{s:5:"title";s:48:"如何在 vTiger 5.1 中使用手机扩展模块";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=755";s:11:"description";s:830:"假设当前你已经成功的安装了手机扩展模块。 +

";s:14:"date_timestamp";i:1276136267;}i:13;a:8:{s:5:"title";s:48:"如何在 vTiger 5.1 中使用手机扩展模块";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=755";s:11:"description";s:830:"假设当前你已经成功的安装了手机扩展模块。 使用手机访问的地址为: @@ -172,7 +230,7 @@ http://192.168.1.102/modules/Mobile[/url] 在你手机上输入上述地址,如果你的这个模块是部署在公共网 ...


-

";s:14:"date_timestamp";i:1276099691;}i:11;a:8:{s:5:"title";s:41:"vtiger 5.1 手机扩展模块安装过程";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=754";s:11:"description";s:831:"vTiger CRM 的移动扩展模块主要是向移动设备能够提供一个基本的 WEB 界面。 +

";s:14:"date_timestamp";i:1276099691;}i:14;a:8:{s:5:"title";s:41:"vtiger 5.1 手机扩展模块安装过程";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=754";s:11:"description";s:831:"vTiger CRM 的移动扩展模块主要是向移动设备能够提供一个基本的 WEB 界面。 首先你需要下载 Mobile 的扩展插件,插件版本被表述为 Mobile-x.y.zip, 你可以通过 Google 进行搜索,也可以在本站里面查找。 @@ -188,11 +246,11 @@ http://192.168.1.102/modules/Mobile[/url] [url=http://forums.hawebs.net/computer/ ...


-

";s:14:"date_timestamp";i:1276098343;}i:12;a:8:{s:5:"title";s:52:"vtiger CRM 5.1.0手机扩展插件的安装与使用";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=752";s:11:"description";s:565:"不多说了.有需要的朋友自己去下载附件,自己去安装使用 +

";s:14:"date_timestamp";i:1276098343;}i:15;a:8:{s:5:"title";s:52:"vtiger CRM 5.1.0手机扩展插件的安装与使用";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=752";s:11:"description";s:565:"不多说了.有需要的朋友自己去下载附件,自己去安装使用


";s:8:"category";s:6:"Vtiger";s:6:"author";s:7:"dasunny";s:7:"pubdate";s:31:"Wed, 09 Jun 2010 01:20:35 +0000";s:7:"summary";s:565:"不多说了.有需要的朋友自己去下载附件,自己去安装使用


-

";s:14:"date_timestamp";i:1276046435;}i:13;a:8:{s:5:"title";s:73:"发一个极品帖vtiger CRM的主要目录结构及主要数据库结构";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=749";s:11:"description";s:609:"[i=s] 本帖最后由 dasunny 于 2010-6-8 17:45 编辑 [/i] +

";s:14:"date_timestamp";i:1276046435;}i:16;a:8:{s:5:"title";s:73:"发一个极品帖vtiger CRM的主要目录结构及主要数据库结构";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=749";s:11:"description";s:609:"[i=s] 本帖最后由 dasunny 于 2010-6-8 17:45 编辑 [/i] 找了很久的好东西,在这里贴出来大家共享.


@@ -200,7 +258,7 @@ http://192.168.1.102/modules/Mobile[/url] 找了很久的好东西,在这里贴出来大家共享.


-

";s:14:"date_timestamp";i:1275987412;}i:14;a:8:{s:5:"title";s:32:"VT显示模块和子模块问题";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=748";s:11:"description";s:866:"现在我有一个职位的权限只有“网页邮件”和“日程安排” +

";s:14:"date_timestamp";i:1275987412;}i:17;a:8:{s:5:"title";s:32:"VT显示模块和子模块问题";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=748";s:11:"description";s:866:"现在我有一个职位的权限只有“网页邮件”和“日程安排” 但登录后还是显示4个模块 @@ -216,7 +274,7 @@ http://192.168.1.102/modules/Mobile[/url] 因为除工作台外的那三个模块下都有“网页邮件”或“日程安排”,这样就显得有些多余,怎么给他去掉呢,还有很多模块下都存在这样的问题,不同模块下拥有相同子模块,比如“ ...


-

";s:14:"date_timestamp";i:1275978656;}i:15;a:8:{s:5:"title";s:18:"vtiger权限问题";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=745";s:11:"description";s:692:"用户管理里有: +

";s:14:"date_timestamp";i:1275978656;}i:18;a:8:{s:5:"title";s:18:"vtiger权限问题";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=745";s:11:"description";s:692:"用户管理里有: 用户、职位、权限、用户组 @@ -232,7 +290,7 @@ http://192.168.1.102/modules/Mobile[/url] 比如分配某个权限给职位,然后职位属于某个组还是怎么样呢?求解


-

";s:14:"date_timestamp";i:1275958515;}i:16;a:8:{s:5:"title";s:52:"求助 vitger在添加新记录时添加时间错误";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=744";s:11:"description";s:673:"我6月8号早上8点45分添加的一条记录,但添加完一查看时间却是:2010-06-08 00:42:42 +

";s:14:"date_timestamp";i:1275958515;}i:19;a:8:{s:5:"title";s:52:"求助 vitger在添加新记录时添加时间错误";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=744";s:11:"description";s:673:"我6月8号早上8点45分添加的一条记录,但添加完一查看时间却是:2010-06-08 00:42:42 有人遇到类似的问题吗,或者谁知道解决办法 @@ -244,36 +302,6 @@ http://192.168.1.102/modules/Mobile[/url] 1263[/attach]


-

";s:14:"date_timestamp";i:1275958069;}i:17;a:8:{s:5:"title";s:76:"求助vtiger CRM 5.1.0中文汉化版本导出生产的PDF文档中文乱码";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=743";s:11:"description";s:619:"我在用vtiger CRM 5.1.0中文汉化版本导出的PDF文档中文部分是乱码,望高手帮忙看看 -如下图 -1261[/attach] -


-

";s:8:"category";s:6:"Vtiger";s:6:"author";s:7:"dasunny";s:7:"pubdate";s:31:"Mon, 07 Jun 2010 11:15:18 +0000";s:7:"summary";s:619:"我在用vtiger CRM 5.1.0中文汉化版本导出的PDF文档中文部分是乱码,望高手帮忙看看 -如下图 -1261[/attach] -


-

";s:14:"date_timestamp";i:1275909318;}i:18;a:8:{s:5:"title";s:70:"目前找到最完美的vtiger CRM 5.1.0简体中文包与安装教程";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=742";s:11:"description";s:641:"vtiger CRM 5.1.0 简体中文包 - -下载地址:http://www.xdowns.com/soft/softdown.asp?softid=61300[/url] - 安装教程在附件里,大家自己下载 -


-

";s:8:"category";s:6:"Vtiger";s:6:"author";s:7:"dasunny";s:7:"pubdate";s:31:"Mon, 07 Jun 2010 08:12:03 +0000";s:7:"summary";s:641:"vtiger CRM 5.1.0 简体中文包 - -下载地址:http://www.xdowns.com/soft/softdown.asp?softid=61300[/url] - 安装教程在附件里,大家自己下载 -


-

";s:14:"date_timestamp";i:1275898323;}i:19;a:8:{s:5:"title";s:51:"vTiger 5.1 邮件扫描 Trouble Ticket 更新规则";s:4:"link";s:56:"http://forums.hawebs.net/computer/viewthread.php?tid=687";s:11:"description";s:824:"在 vTiger 5.1 进行邮件扫描时,使用正则表达式对用户回复的邮件的主题进行匹配。 - -如果成功后,将会更新指定 Trouble Ticket ID 的状态。 - -其正则表达式为:Ticket Id[^:]?: ([0-9]+)[/code]如果用户回复邮件的主题为:RE: TT13 [ Ticket Id : 140 ] Re : 服务请求[/code]那 ... -


-

";s:8:"category";s:6:"Vtiger";s:6:"author";s:10:"honeymoose";s:7:"pubdate";s:31:"Mon, 31 May 2010 20:39:00 +0000";s:7:"summary";s:824:"在 vTiger 5.1 进行邮件扫描时,使用正则表达式对用户回复的邮件的主题进行匹配。 - -如果成功后,将会更新指定 Trouble Ticket ID 的状态。 - -其正则表达式为:Ticket Id[^:]?: ([0-9]+)[/code]如果用户回复邮件的主题为:RE: TT13 [ Ticket Id : 140 ] Re : 服务请求[/code]那 ... -


-

";s:14:"date_timestamp";i:1275338340;}}s:7:"channel";a:8:{s:5:"title";s:25:"OSS 计算技术 - Vtiger";s:4:"link";s:57:"http://forums.hawebs.net/computer/forumdisplay.php?fid=50";s:11:"description";s:27:"Latest 20 threads of Vtiger";s:9:"copyright";s:29:"Copyright(C) OSS 计算技术";s:9:"generator";s:13:"HX WEBSYSTEMS";s:13:"lastbuilddate";s:31:"Thu, 17 Jun 2010 14:53:45 +0000";s:3:"ttl";s:2:"30";s:7:"tagline";s:27:"Latest 20 threads of Vtiger";}s:9:"textinput";a:0:{}s:5:"image";a:3:{s:3:"url";s:49:"http://forums.hawebs.net/computer/images/logo.gif";s:5:"title";s:16:"OSS 计算技术";s:4:"link";s:34:"http://forums.hawebs.net/computer/";}s:9:"feed_type";s:3:"RSS";s:12:"feed_version";s:3:"2.0";s:8:"encoding";s:5:"UTF-8";s:16:"_source_encoding";s:0:"";s:5:"ERROR";s:0:"";s:7:"WARNING";s:0:"";s:19:"_CONTENT_CONSTRUCTS";a:6:{i:0;s:7:"content";i:1;s:7:"summary";i:2;s:4:"info";i:3;s:5:"title";i:4;s:7:"tagline";i:5;s:9:"copyright";}s:16:"_KNOWN_ENCODINGS";a:3:{i:0;s:5:"UTF-8";i:1;s:8:"US-ASCII";i:2;s:10:"ISO-8859-1";}s:5:"stack";a:0:{}s:9:"inchannel";b:0;s:6:"initem";b:0;s:9:"incontent";b:0;s:11:"intextinput";b:0;s:7:"inimage";b:0;s:17:"current_namespace";b:0;s:13:"last_modified";s:31:"Thu, 17 Jun 2010 14:57:56 GMT -";s:4:"etag";s:29:"usZRTNF8BzcbMKnEIYmXsVmlSNQ +

";s:14:"date_timestamp";i:1275958069;}}s:7:"channel";a:8:{s:5:"title";s:25:"OSS 计算技术 - Vtiger";s:4:"link";s:57:"http://forums.hawebs.net/computer/forumdisplay.php?fid=50";s:11:"description";s:27:"Latest 20 threads of Vtiger";s:9:"copyright";s:29:"Copyright(C) OSS 计算技术";s:9:"generator";s:13:"HX WEBSYSTEMS";s:13:"lastbuilddate";s:31:"Fri, 18 Jun 2010 21:57:35 +0000";s:3:"ttl";s:2:"30";s:7:"tagline";s:27:"Latest 20 threads of Vtiger";}s:9:"textinput";a:0:{}s:5:"image";a:3:{s:3:"url";s:49:"http://forums.hawebs.net/computer/images/logo.gif";s:5:"title";s:16:"OSS 计算技术";s:4:"link";s:34:"http://forums.hawebs.net/computer/";}s:9:"feed_type";s:3:"RSS";s:12:"feed_version";s:3:"2.0";s:8:"encoding";s:5:"UTF-8";s:16:"_source_encoding";s:0:"";s:5:"ERROR";s:0:"";s:7:"WARNING";s:0:"";s:19:"_CONTENT_CONSTRUCTS";a:6:{i:0;s:7:"content";i:1;s:7:"summary";i:2;s:4:"info";i:3;s:5:"title";i:4;s:7:"tagline";i:5;s:9:"copyright";}s:16:"_KNOWN_ENCODINGS";a:3:{i:0;s:5:"UTF-8";i:1;s:8:"US-ASCII";i:2;s:10:"ISO-8859-1";}s:5:"stack";a:0:{}s:9:"inchannel";b:0;s:6:"initem";b:0;s:9:"incontent";b:0;s:11:"intextinput";b:0;s:7:"inimage";b:0;s:17:"current_namespace";b:0;s:13:"last_modified";s:31:"Fri, 18 Jun 2010 21:57:37 GMT +";s:4:"etag";s:29:"pnSP1GkzAR7kAw1LFKf0ONj7X6s ";} \ No newline at end of file diff --git a/oss/vtiger/trunk/include/database/PearDatabase.php b/oss/vtiger/trunk/include/database/PearDatabase.php new file mode 100644 index 00000000..9bcc07fb --- /dev/null +++ b/oss/vtiger/trunk/include/database/PearDatabase.php @@ -0,0 +1,1148 @@ +ctr = 0; + $this->vals = $vals; + } + function call($matches){ + /** + * If ? is found as expected in regex used in function convert2sql + * /('[^']*')|(\"[^\"]*\")|([?])/ + * + */ + if($matches[3]=='?'){ + $this->ctr++; + return $this->vals[$this->ctr-1]; + }else{ + return $matches[0]; + } + } +} + +/** + * Performance perference API + */ +@include_once('config.performance.php'); // Ignore warning if not present +class PerformancePrefs { + /** + * Get performance parameter configured value or default one + */ + static function get($key, $defvalue=false) { + global $PERFORMANCE_CONFIG; + if(isset($PERFORMANCE_CONFIG)){ + if(isset($PERFORMANCE_CONFIG[$key])) { + return $PERFORMANCE_CONFIG[$key]; + } + } + return $defvalue; + } + /** Get boolean value */ + static function getBoolean($key, $defvalue=false) { + return self::get($key, $defvalue); + } + /** Get Integer value */ + static function getInteger($key, $defvalue=false) { + return intval(self::get($key, $defvalue)); + } +} + +/** + * Cache Class for PearDatabase + */ +class PearDatabaseCache { + var $_queryResultCache = Array(); + var $_parent; + + // Cache the result if rows is less than this + var $_CACHE_RESULT_ROW_LIMIT; + + /** + * Constructor + */ + function __construct($parent) { + $this->_parent = $parent; + $this->_CACHE_RESULT_ROW_LIMIT = PerformancePrefs::getInteger('CACHE_RESULT_ROW_LIMIT', 100); + } + + /** + * Reset the cache contents + */ + function resetCache() { + unset($this->_queryResultCache); + $this->_queryResultCache = Array(); + } + + /** + * Cache SQL Query Result (perferably only SELECT SQL) + */ + function cacheResult($result, $sql, $params=false) { + // We don't want to cache NON-SELECT query results now + if(stripos(trim($sql), 'SELECT ') !== 0) { + return; + } + // If the result is too big, don't cache it + if($this->_parent->num_rows($result) > $this->_CACHE_RESULT_ROW_LIMIT) { + global $log; + $log->fatal("[" . get_class($this) . "] Cannot cache result! $sql [Exceeds limit ". + $this->_CACHE_RESULT_ROW_LIMIT . ", Total Rows " . $this->_parent->num_rows($result) . "]"); + return false; + } + $usekey = $sql; + if(!empty($params)) $usekey = $this->_parent->convert2Sql($sql, $this->_parent->flatten_array($params)); + $this->_queryResultCache[$usekey] = $result; + } + + /** + * Get the cached result for re-use + */ + function getCacheResult($sql, $params=false) { + $result = false; + $usekey = $sql; + if(!empty($params)) $usekey = $this->_parent->convert2Sql($sql, $this->_parent->flatten_array($params)); + $result = $this->_queryResultCache[$usekey]; + // Rewind the result for re-use + if($result) { + // If result not in use rewind it + if($result->EOF) $result->MoveFirst(); + else if($result->CurrentRow() != 0) { + global $log; + $log->fatal("[" . get_class($this) . "] Cannot reuse result! $usekey [Rows Total " . + $this->_parent->num_rows($result) . ", Currently At: " . $result->CurrentRow() . "]"); + // Do no allow result to be re-used if it is in use. + $result = false; + } + } + return $result; + } +} + +class PearDatabase{ + var $database = null; + var $dieOnError = false; + var $dbType = null; + var $dbHostName = null; + var $dbName = null; + var $dbOptions = null; + var $userName=null; + var $userPassword=null; + var $query_time = 0; + var $log = null; + var $lastmysqlrow = -1; + var $enableSQLlog = false; + var $continueInstallOnError = true; + + // If you want to avoid executing PreparedStatement, set this to true + // PreparedStatement will be converted to normal SQL statement for execution + var $avoidPreparedSql = false; + + /** + * Performance tunning parameters (can be configured through performance.prefs.php) + * See the constructor for initialization + */ + var $isdb_default_utf8_charset = false; + var $enableCache = false; + + var $_cacheinstance = false; // Will be auto-matically initialized if $enableCache is true + /** + * API's to control cache behavior + */ + function __setCacheInstance($cacheInstance) { + $this->_cacheinstance = $cacheInstance; + } + /** Return the cache instance reference (using &) */ + function &getCacheInstance() { + return $this->_cacheinstance; + } + function isCacheEnabled() { + return ($this->enableCache && ($this->getCacheInstance() != false)); + } + function clearCache() { + if($this->isCacheEnabled()) $this->getCacheInstance()->resetCache(); + } + function toggleCache($newstatus) { + $oldstatus = $this->enableCache; + $this->enableCache = $newstatus; + return $oldstatus; + } + // END + + /** + * Manage instance usage of this class + */ + static function &getInstance() { + global $adb, $log; + + $multiConnection = PerformancePrefs::getBoolean('ALLOW_MULTI_DB_CONNECTION_PER_REQUEST', true); + if(!$multiConnection) { + // Reuse the instance + if(!isset($adb)) { + $adb = new self(); + } + return $adb; + } else { + // Create new instance + return (new self()); + } + } + // END + + /* + * Reset query result for resuing if cache is enabled. + */ + function resetQueryResultToEOF(&$result) { + if($result) { + if($result->MoveLast()) { + $result->MoveNext(); + } + } + } + // END + + function isMySQL() { return (stripos($this->dbType ,'mysql') === 0);} + function isOracle() { return $this->dbType=='oci8'; } + function isPostgres() { return $this->dbType=='pgsql'; } + + function println($msg) + { + require_once('include/logging.php'); + $log1 =& LoggerManager::getLogger('VT'); + if(is_array($msg)) { + $log1->info("PearDatabse ->".print_r($msg,true)); + } else { + $log1->info("PearDatabase ->".$msg); + } + return $msg; + } + + function setDieOnError($value){ $this->dieOnError = $value; } + function setDatabaseType($type){ $this->dbType = $type; } + function setUserName($name){ $this->userName = $name; } + + function setOption($name, $value){ + if(isset($this->dbOptions)) $this->dbOptions[$name] = $value; + if(isset($this->database)) $this->database->setOption($name, $value); + } + + function setUserPassword($pass){ $this->userPassword = $pass; } + function setDatabaseName($db){ $this->dbName = $db; } + function setDatabaseHost($host){ $this->dbHostName = $host; } + + function getDataSourceName(){ + return $this->dbType. "://".$this->userName.":".$this->userPassword."@". $this->dbHostName . "/". $this->dbName; + } + + function startTransaction() { + if($this->isPostgres()) return; + $this->checkConnection(); + $this->println("TRANS Started"); + $this->database->StartTrans(); + } + + function completeTransaction() { + if($this->isPostgres()) return; + if($this->database->HasFailedTrans()) $this->println("TRANS Rolled Back"); + else $this->println("TRANS Commited"); + + $this->database->CompleteTrans(); + $this->println("TRANS Completed"); + } + + function hasFailedTransaction(){ return $this->database->HasFailedTrans(); } + + function checkError($msg='', $dieOnError=false) { + if($this->dieOnError || $dieOnError) { + $this->println("ADODB error ".$msg."->[".$this->database->ErrorNo()."]".$this->database->ErrorMsg()); + die ($msg."ADODB error ".$msg."->".$this->database->ErrorMsg()); + } else { + $this->println("ADODB error ".$msg."->[".$this->database->ErrorNo()."]".$this->database->ErrorMsg()); + } + return false; + } + + function change_key_case($arr) { + return is_array($arr)?array_change_key_case($arr):$arr; + } + + var $req_flist; + function checkConnection(){ + global $log; + + if(!isset($this->database)) { + $this->println("TRANS creating new connection"); + $this->connect(false); + } else { + //$this->println("checkconnect using old connection"); + } + } + + /** + * Put out the SQL timing information + */ + function logSqlTiming($startat, $endat, $sql, $params=false) { + global $logsqltm; + // Specifically for timing the SQL execution, you need to enable DEBUG in log4php.properties + if($logsqltm->isDebugEnabled()){ + if(PerformancePrefs::getBoolean('SQL_LOG_INCLUDE_CALLER', false)) { + $callers = debug_backtrace(); + $callerscount = count($callers); + $callerfunc = ''; + for($calleridx = 0; $calleridx < $callerscount; ++$calleridx) { + if($calleridx == 0) { + // Ignore the first caller information, it will be generally from this file! + continue; + } + // Caller function will be in next information block + if($calleridx < $callerscount) { + $callerfunc = $callers[$calleridx+1]['function']; + if(!empty($callerfunc)) $callerfunc = " ($callerfunc) "; + } + $logsqltm->debug( + "CALLER: (" . $callers[$calleridx]['line'] . ') ' . + $callers[$calleridx]['file'] . $callerfunc); + } + } + $logsqltm->debug("SQL: " . $sql); + if($params != null && count($params) > 0) $logsqltm->debug("PARAMS: [" . implode(",", $params) . "]"); + $logsqltm->debug("EXEC: " . ($endat - $startat) ." micros [START=$startat, END=$endat]"); + $logsqltm->debug(""); + } + } + + /** + * Execute SET NAMES UTF-8 on the connection based on configuration. + */ + function executeSetNamesUTF8SQL($force = false) { + global $default_charset; + // Performance Tuning: If database default charset is UTF-8, we don't need this + if(strtoupper($default_charset) == 'UTF-8' && ($force || !$this->isdb_default_utf8_charset)) { + + $sql_start_time = microtime(true); + + $setnameSql = "SET NAMES utf8"; + $this->database->Execute($setnameSql); + $this->logSqlTiming($sql_start_time, microtime(true), $setnameSql); + } + } + + /** + * Execute query in a batch. + * + * For example: + * INSERT INTO TABLE1 VALUES (a,b); + * INSERT INTO TABLE1 VALUES (c,d); + * + * like: INSERT INTO TABLE1 VALUES (a,b), (c,d) + */ + function query_batch($prefixsql, $valuearray) { + if(PerformancePrefs::getBoolean('ALLOW_SQL_QUERY_BATCH')) { + $sql = $prefixsql; + $suffixsql = $valuearray; + if(!is_array($valuearray)) $suffixsql = implode(',', $valuearray); + $this->query($prefixsql . $suffixsql); + } else { + if(is_array($valuearray) && !empty($valuearray)) { + foreach($valuearray as $suffixsql) { + $this->query($prefixsql . $suffixsql); + } + } + } + } + + function query($sql, $dieOnError=false, $msg='') + { + global $log, $default_charset; + // Performance Tuning: Have we cached the result earlier? + if($this->isCacheEnabled()) { + $fromcache = $this->getCacheInstance()->getCacheResult($sql); + if($fromcache) { + $log->debug("Using query result from cache: $sql"); + return $fromcache; + } + } + // END + $log->debug('query being executed : '.$sql); + $this->checkConnection(); + + $this->executeSetNamesUTF8SQL(); + + $sql_start_time = microtime(true); + $result = & $this->database->Execute($sql); + $this->logSqlTiming($sql_start_time, microtime(true), $sql); + + $this->lastmysqlrow = -1; + if(!$result)$this->checkError($msg.' Query Failed:' . $sql . '::', $dieOnError); + + // Performance Tuning: Cache the query result + if($this->isCacheEnabled()) { + $this->getCacheInstance()->cacheResult($result, $sql); + } + // END + return $result; + } + + + /** + * Convert PreparedStatement to SQL statement + */ + function convert2Sql($ps, $vals) { + if(empty($vals)) { return $ps; } + // TODO: Checks need to be added array out of bounds situations + for($index = 0; $index < count($vals); $index++) { + // Package import pushes data after XML parsing, so type-cast it + if(is_a($vals[$index], 'SimpleXMLElement')) { + $vals[$index] = (string) $vals[$index]; + } + if(is_string($vals[$index])) { + if($vals[$index] == '') { + $vals[$index] = $this->database->Quote($vals[$index]); + } + else { + $vals[$index] = "'".$this->sql_escape_string($vals[$index]). "'"; + } + } + if($vals[$index] === null) { + $vals[$index] = "NULL"; + } + } + $sql = preg_replace_callback("/('[^']*')|(\"[^\"]*\")|([?])/", array(new PreparedQMark2SqlValue($vals),"call"), $ps); + return $sql; + } + + /* ADODB prepared statement Execution + * @param $sql -- Prepared sql statement + * @param $params -- Parameters for the prepared statement + * @param $dieOnError -- Set to true, when query execution fails + * @param $msg -- Error message on query execution failure + */ + function pquery($sql, $params, $dieOnError=false, $msg='') { + global $log, $default_charset; + // Performance Tuning: Have we cached the result earlier? + if($this->isCacheEnabled()) { + $fromcache = $this->getCacheInstance()->getCacheResult($sql, $params); + if($fromcache) { + $log->debug("Using query result from cache: $sql"); + return $fromcache; + } + } + // END + $log->debug('Prepared sql query being executed : '.$sql); + $this->checkConnection(); + + $this->executeSetNamesUTF8SQL(); + + $sql_start_time = microtime(true); + $params = $this->flatten_array($params); + if (count($params) > 0) { + $log->debug('Prepared sql query parameters : [' . implode(",", $params) . ']'); + } + + if($this->avoidPreparedSql || empty($params)) { + $sql = $this->convert2Sql($sql, $params); + $result = &$this->database->Execute($sql); + } else { + $result = &$this->database->Execute($sql, $params); + } + $sql_end_time = microtime(true); + $this->logSqlTiming($sql_start_time, $sql_end_time, $sql, $params); + + $this->lastmysqlrow = -1; + if(!$result)$this->checkError($msg.' Query Failed:' . $sql . '::', $dieOnError); + + // Performance Tuning: Cache the query result + if($this->isCacheEnabled()) { + $this->getCacheInstance()->cacheResult($result, $sql, $params); + } + // END + return $result; + } + + /** + * Flatten the composite array into single value. + * Example: + * $input = array(10, 20, array(30, 40), array('key1' => '50', 'key2'=>array(60), 70)); + * returns array(10, 20, 30, 40, 50, 60, 70); + */ + function flatten_array($input, $output=null) { + if($input == null) return null; + if($output == null) $output = array(); + foreach($input as $value) { + if(is_array($value)) { + $output = $this->flatten_array($value, $output); + } else { + array_push($output, $value); + } + } + return $output; + } + + function getEmptyBlob($is_string=true) + { + //if(dbType=="oci8") return 'empty_blob()'; + //else return 'null'; + if (is_string) return 'null'; + return null; + } + + function updateBlob($tablename, $colname, $id, $data) + { + $this->println("updateBlob t=".$tablename." c=".$colname." id=".$id); + $this->checkConnection(); + $this->executeSetNamesUTF8SQL(); + + $sql_start_time = microtime(true); + $result = $this->database->UpdateBlob($tablename, $colname, $data, $id); + $this->logSqlTiming($sql_start_time, microtime(true), "Update Blob $tablename, $colname, $id"); + + $this->println("updateBlob t=".$tablename." c=".$colname." id=".$id." status=".$result); + return $result; + } + + function updateBlobFile($tablename, $colname, $id, $filename) + { + $this->println("updateBlobFile t=".$tablename." c=".$colname." id=".$id." f=".$filename); + $this->checkConnection(); + $this->executeSetNamesUTF8SQL(); + + $sql_start_time = microtime(true); + $result = $this->database->UpdateBlobFile($tablename, $colname, $filename, $id); + $this->logSqlTiming($sql_start_time, microtime(true), "Update Blob $tablename, $colname, $id"); + + $this->println("updateBlobFile t=".$tablename." c=".$colname." id=".$id." f=".$filename." status=".$result); + return $result; + } + + function limitQuery($sql,$start,$count, $dieOnError=false, $msg='') + { + global $log; + //$this->println("ADODB limitQuery sql=".$sql." st=".$start." co=".$count); + $log->debug(' limitQuery sql = '.$sql .' st = '.$start .' co = '.$count); + $this->checkConnection(); + + $this->executeSetNamesUTF8SQL(); + + $sql_start_time = microtime(true); + $result =& $this->database->SelectLimit($sql,$count,$start); + $this->logSqlTiming($sql_start_time, microtime(true), "$sql LIMIT $count, $start"); + + if(!$result) $this->checkError($msg.' Limit Query Failed:' . $sql . '::', $dieOnError); + return $result; + } + + function getOne($sql, $dieOnError=false, $msg='') + { + $this->println("ADODB getOne sql=".$sql); + $this->checkConnection(); + + $this->executeSetNamesUTF8SQL(); + + $sql_start_time = microtime(true); + $result =& $this->database->GetOne($sql); + $this->logSqlTiming($sql_start_time, microtime(true), "$sql GetONE"); + + if(!$result) $this->checkError($msg.' Get one Query Failed:' . $sql . '::', $dieOnError); + return $result; + } + + function getFieldsDefinition(&$result) + { + //$this->println("ADODB getFieldsArray"); + $field_array = array(); + if(! isset($result) || empty($result)) + { + return 0; + } + + $i = 0; + $n = $result->FieldCount(); + while ($i < $n) + { + $meta = $result->FetchField($i); + if (!$meta) + { + return 0; + } + array_push($field_array,$meta); + $i++; + } + + //$this->println($field_array); + return $field_array; + } + + function getFieldsArray(&$result) + { + //$this->println("ADODB getFieldsArray"); + $field_array = array(); + if(! isset($result) || empty($result)) + { + return 0; + } + + $i = 0; + $n = $result->FieldCount(); + while ($i < $n) + { + $meta = $result->FetchField($i); + if (!$meta) + { + return 0; + } + array_push($field_array,$meta->name); + $i++; + } + + //$this->println($field_array); + return $field_array; + } + + function getRowCount(&$result){ + global $log; + if(isset($result) && !empty($result)) + $rows= $result->RecordCount(); + return $rows; + } + + /* ADODB newly added. replacement for mysql_num_rows */ + function num_rows(&$result) { + return $this->getRowCount($result); + } + + /* ADODB newly added. replacement form mysql_num_fields */ + function num_fields(&$result) { + return $result->FieldCount(); + } + + /* ADODB newly added. replacement for mysql_fetch_array() */ + function fetch_array(&$result) { + if($result->EOF) { + //$this->println("ADODB fetch_array return null"); + return NULL; + } + $arr = $result->FetchRow(); + if(is_array($arr)) + $arr = array_map('to_html', $arr); + return $this->change_key_case($arr); + } + + ## adds new functions to the PearDatabase class to come around the whole + ## broken query_result() idea + ## Code-Contribution given by weigelt@metux.de - Starts + function run_query_record_html($query) { + if (!is_array($rec = $this->run_query_record($query))) + return $rec; + foreach ($rec as $walk => $cur) + $r[$walk] = to_html($cur); + return $r; + } + + function sql_quote($data) { + if (is_array($data)) { + switch($data{'type'}) { + case 'text': + case 'numeric': + case 'integer': + case 'oid': + return $this->quote($data{'value'}); + break; + case 'timestamp': + return $this->formatDate($data{'value'}); + break; + default: + throw new Exception("unhandled type: ".serialize($cur)); + } + } else + return $this->quote($data); + } + + function sql_insert_data($table, $data) { + if (!$table) + throw new Exception("missing table name"); + if (!is_array($data)) + throw new Exception("data must be an array"); + if (!count($table)) + throw new Exception("no data given"); + + $sql_fields = ''; + $sql_data = ''; + foreach($data as $walk => $cur) { + $sql_fields .= ($sql_fields?',':'').$walk; + $sql_data .= ($sql_data?',':'').$this->sql_quote($cur); + } + return 'INSERT INTO '.$table.' ('.$sql_fields.') VALUES ('.$sql_data.')'; + } + + function run_insert_data($table,$data) { + $query = $this->sql_insert_data($table,$data); + $res = $this->query($query); + $this->query("commit;"); + } + + function run_query_record($query) { + $result = $this->query($query); + if (!$result) + return; + if (!is_object($result)) + throw new Exception("query \"$query\" failed: ".serialize($result)); + $res = $result->FetchRow(); + $rowdata = $this->change_key_case($res); + return $rowdata; + } + + function run_query_allrecords($query) { + $result = $this->query($query); + $records = array(); + $sz = $this->num_rows($result); + for ($i=0; $i<$sz; $i++) + $records[$i] = $this->change_key_case($result->FetchRow()); + return $records; + } + + function run_query_field($query,$field='') { + $rowdata = $this->run_query_record($query); + if(isset($field) && $field != '') + return $rowdata{$field}; + else + return array_shift($rowdata); + } + + function run_query_list($query,$field){ + $records = $this->run_query_allrecords($query); + foreach($records as $walk => $cur) + $list[] = $cur{$field}; + } + + function run_query_field_html($query,$field){ + return to_html($this->run_query_field($query,$field)); + } + + function result_get_next_record($result){ + return $this->change_key_case($result->FetchRow()); + } + + // create an IN expression from an array/list + function sql_expr_datalist($a) { + if (!is_array($a)) + throw new Exception("not an array"); + if (!count($a)) + throw new Exception("empty arrays not allowed"); + + foreach($a as $walk => $cur) + $l .= ($l?',':'').$this->quote($cur); + return ' ( '.$l.' ) '; + } + + // create an IN expression from an record list, take $field within each record + function sql_expr_datalist_from_records($a,$field) { + if (!is_array($a)) + throw new Exception("not an array"); + if (!$field) + throw new Exception("missing field"); + if (!count($a)) + throw new Exception("empty arrays not allowed"); + + foreach($a as $walk => $cur) + $l .= ($l?',':'').$this->quote($cur{$field}); + + return ' ( '.$l.' ) '; + } + + function sql_concat($list) { + switch ($this->dbType) { + case 'mysql': + return 'concat('.implode(',',$list).')'; + case 'pgsql': + return '('.implode('||',$list).')'; + default: + throw new Exception("unsupported dbtype \"".$this->dbType."\""); + } + } + ## Code-Contribution given by weigelt@metux.de - Ends + + /* ADODB newly added. replacement for mysql_result() */ + function query_result(&$result, $row, $col=0) { + if (!is_object($result)) + throw new Exception("result is not an object"); + $result->Move($row); + $rowdata = $this->change_key_case($result->FetchRow()); + //$this->println($rowdata); + //Commented strip_selected_tags and added to_html function for HTML tags vulnerability + if($col == 'fieldlabel') $coldata = $rowdata[$col]; + else $coldata = to_html($rowdata[$col]); + return $coldata; + } + + // Function to get particular row from the query result + function query_result_rowdata(&$result, $row=0) { + if (!is_object($result)) + throw new Exception("result is not an object"); + $result->Move($row); + $rowdata = $this->change_key_case($result->FetchRow()); + + foreach($rowdata as $col => $coldata) { + if($col != 'fieldlabel') + $rowdata[$col] = to_html($coldata); + } + return $rowdata; + } + + /** + * Get an array representing a row in the result set + * Unlike it's non raw siblings this method will not escape + * html entities in return strings. + * + * The case of all the field names is converted to lower case. + * as with the other methods. + * + * @param &$result The query result to fetch from. + * @param $row The row number to fetch. It's default value is 0 + * + */ + function raw_query_result_rowdata(&$result, $row=0) { + if (!is_object($result)) + throw new Exception("result is not an object"); + $result->Move($row); + $rowdata = $this->change_key_case($result->FetchRow()); + return $rowdata; + } + + + + function getAffectedRowCount(&$result){ + global $log; + $log->debug('getAffectedRowCount'); + $rows =$this->database->Affected_Rows(); + $log->debug('getAffectedRowCount rows = '.$rows); + return $rows; + } + + function requireSingleResult($sql, $dieOnError=false,$msg='', $encode=true) { + $result = $this->query($sql, $dieOnError, $msg); + + if($this->getRowCount($result ) == 1) + return $result; + $this->log->error('Rows Returned:'. $this->getRowCount($result) .' More than 1 row returned for '. $sql); + return ''; + } + /* function which extends requireSingleResult api to execute prepared statment + */ + + function requirePsSingleResult($sql, $params, $dieOnError=false,$msg='', $encode=true) { + $result = $this->pquery($sql, $params, $dieOnError, $msg); + + if($this->getRowCount($result ) == 1) + return $result; + $this->log->error('Rows Returned:'. $this->getRowCount($result) .' More than 1 row returned for '. $sql); + return ''; + } + + function fetchByAssoc(&$result, $rowNum = -1, $encode=true) { + if($result->EOF) { + $this->println("ADODB fetchByAssoc return null"); + return NULL; + } + if(isset($result) && $rowNum < 0) { + $row = $this->change_key_case($result->GetRowAssoc(false)); + $result->MoveNext(); + if($encode&& is_array($row)) + return array_map('to_html', $row); + return $row; + } + + if($this->getRowCount($result) > $rowNum) { + $result->Move($rowNum); + } + $this->lastmysqlrow = $rowNum; + $row = $this->change_key_case($result->GetRowAssoc(false)); + $result->MoveNext(); + $this->println($row); + + if($encode&& is_array($row)) + return array_map('to_html', $row); + return $row; + } + + function getNextRow(&$result, $encode=true){ + global $log; + $log->info('getNextRow'); + if(isset($result)){ + $row = $this->change_key_case($result->FetchRow()); + if($row && $encode&& is_array($row)) + return array_map('to_html', $row); + return $row; + } + return null; + } + + function fetch_row(&$result, $encode=true) { + return $this->getNextRow($result); + } + + function field_name(&$result, $col) { + return $result->FetchField($col); + } + + function getQueryTime(){ + return $this->query_time; + } + + function connect($dieOnError = false) { + global $dbconfigoption,$dbconfig; + if(!isset($this->dbType)) { + $this->println("ADODB Connect : DBType not specified"); + return; + } + $this->database = ADONewConnection($this->dbType); + + $this->database->PConnect($this->dbHostName, $this->userName, $this->userPassword, $this->dbName); + $this->database->LogSQL($this->enableSQLlog); + + // 'SET NAMES UTF8' needs to be executed even if database has default CHARSET UTF8 + // as mysql server might be running with different charset! + // We will notice problem reading UTF8 characters otherwise. + if($this->isdb_default_utf8_charset) { + $this->executeSetNamesUTF8SQL(true); + } + } + + /** + * Constructor + */ + function PearDatabase($dbtype='',$host='',$dbname='',$username='',$passwd='') { + global $currentModule; + $this->log =& LoggerManager::getLogger('PearDatabase_'. $currentModule); + $this->resetSettings($dbtype,$host,$dbname,$username,$passwd); + + // Initialize performance parameters + $this->isdb_default_utf8_charset = PerformancePrefs::getBoolean('DB_DEFAULT_CHARSET_UTF8'); + $this->enableCache = PerformancePrefs::getBoolean('CACHE_QUERY_RESULT', false); + // END + + if(!isset($this->dbType)) + { + $this->println("ADODB Connect : DBType not specified"); + return; + } + // Initialize the cache object to use. + if(isset($this->enableCache) && $this->enableCache) { + $this->__setCacheInstance(new PearDatabaseCache($this)); + } + // END + } + + function resetSettings($dbtype,$host,$dbname,$username,$passwd){ + global $dbconfig, $dbconfigoption; + + if($host == '') { + $this->disconnect(); + $this->setDatabaseType($dbconfig['db_type']); + $this->setUserName($dbconfig['db_username']); + $this->setUserPassword($dbconfig['db_password']); + $this->setDatabaseHost( $dbconfig['db_hostname']); + $this->setDatabaseName($dbconfig['db_name']); + $this->dbOptions = $dbconfigoption; + if($dbconfig['log_sql']) + $this->enableSQLlog = ($dbconfig['log_sql'] == true); + } else { + $this->disconnect(); + $this->setDatabaseType($dbtype); + $this->setDatabaseName($dbname); + $this->setUserName($username); + $this->setUserPassword($passwd); + $this->setDatabaseHost( $host); + } + } + + function quote($string){ + return $this->database->qstr($string); + } + + function disconnect() { + $this->println("ADODB disconnect"); + if(isset($this->database)){ + if($this->dbType == "mysql"){ + mysql_close($this->database); + } else { + $this->database->disconnect(); + } + unset($this->database); + } + } + + function setDebug($value) { + $this->database->debug = $value; + } + + // ADODB newly added methods + function createTables($schemaFile, $dbHostName=false, $userName=false, $userPassword=false, $dbName=false, $dbType=false) { + $this->println("ADODB createTables ".$schemaFile); + if($dbHostName!=false) $this->dbHostName=$dbHostName; + if($userName!=false) $this->userName=$userPassword; + if($userPassword!=false) $this->userPassword=$userPassword; + if($dbName!=false) $this->dbName=$dbName; + if($dbType!=false) $this->dbType=$dbType; + + $this->checkConnection(); + $db = $this->database; + $schema = new adoSchema( $db ); + //Debug Adodb XML Schema + $sehema->XMLS_DEBUG = TRUE; + //Debug Adodb + $sehema->debug = true; + $sql = $schema->ParseSchema( $schemaFile ); + + $this->println("--------------Starting the table creation------------------"); + $result = $schema->ExecuteSchema( $sql, $this->continueInstallOnError ); + if($result) print $db->errorMsg(); + // needs to return in a decent way + $this->println("ADODB createTables ".$schemaFile." status=".$result); + return $result; + } + + function createTable($tablename, $flds) { + $this->println("ADODB createTable table=".$tablename." flds=".$flds); + $this->checkConnection(); + $dict = NewDataDictionary($this->database); + $sqlarray = $dict->CreateTableSQL($tablename, $flds); + $result = $dict->ExecuteSQLArray($sqlarray); + $this->println("ADODB createTable table=".$tablename." flds=".$flds." status=".$result); + return $result; + } + + function alterTable($tablename, $flds, $oper) { + $this->println("ADODB alterTableTable table=".$tablename." flds=".$flds." oper=".$oper); + $this->checkConnection(); + $dict = NewDataDictionary($this->database); + + if($oper == 'Add_Column') { + $sqlarray = $dict->AddColumnSQL($tablename, $flds); + } else if($oper == 'Delete_Column') { + $sqlarray = $dict->DropColumnSQL($tablename, $flds); + } + $this->println("sqlarray"); + $this->println($sqlarray); + + $result = $dict->ExecuteSQLArray($sqlarray); + + $this->println("ADODB alterTableTable table=".$tablename." flds=".$flds." oper=".$oper." status=".$result); + return $result; + } + + function getColumnNames($tablename) { + $this->println("ADODB getColumnNames table=".$tablename); + $this->checkConnection(); + $adoflds = $this->database->MetaColumns($tablename); + $i=0; + foreach($adoflds as $fld) { + $colNames[$i] = $fld->name; + $i++; + } + return $colNames; + } + + function formatString($tablename,$fldname, $str) { + $this->checkConnection(); + $adoflds = $this->database->MetaColumns($tablename); + + foreach ( $adoflds as $fld ) { + if(strcasecmp($fld->name,$fldname)==0) { + $fldtype =strtoupper($fld->type); + if(strcmp($fldtype,'CHAR')==0 || strcmp($fldtype,'VARCHAR') == 0 || strcmp($fldtype,'VARCHAR2') == 0 || strcmp($fldtype,'LONGTEXT')==0 || strcmp($fldtype,'TEXT')==0) { + return $this->database->Quote($str); + } else if(strcmp($fldtype,'DATE') ==0 || strcmp($fldtype,'TIMESTAMP')==0) { + return $this->formatDate($str); + } else { + return $str; + } + } + } + $this->println("format String Illegal field name ".$fldname); + return $str; + } + + function formatDate($datetime, $strip_quotes=false) { + $this->checkConnection(); + $db = &$this->database; + $date = $db->DBTimeStamp($datetime); + /* Asha: Stripping single quotes to use the date as parameter for Prepared statement */ + if($strip_quotes == true) { + return trim($date, "'"); + } + return $date; + } + + function getDBDateString($datecolname) { + $this->checkConnection(); + $db = &$this->database; + $datestr = $db->SQLDate("Y-m-d, H:i:s" ,$datecolname); + return $datestr; + } + + function getUniqueID($seqname) { + $this->checkConnection(); + return $this->database->GenID($seqname."_seq",1); + } + + function get_tables() { + $this->checkConnection(); + $result = & $this->database->MetaTables('TABLES'); + $this->println($result); + return $result; + } + + //To get a function name with respect to the database type which escapes strings in given text + function sql_escape_string($str) + { + if($this->isMySql()) + $result_data = mysql_real_escape_string($str); + elseif($this->isPostgres()) + $result_data = pg_escape_string($str); + return $result_data; + } + + // Function to get the last insert id based on the type of database + function getLastInsertID($seqname = '') { + if($this->isPostgres()) { + $result = pg_query("SELECT currval('".$seqname."_seq')"); + if($result) + { + $row = pg_fetch_row($result); + $last_insert_id = $row[0]; + } + } else { + $last_insert_id = $this->database->Insert_ID(); + } + return $last_insert_id; + } +} /* End of class */ + +if(empty($adb)) { + $adb = new PearDatabase(); + $adb->connect(); +} +//$adb->database->setFetchMode(ADODB_FETCH_NUM); + +?> diff --git a/oss/vtiger/trunk/include/database/Postgres8.php b/oss/vtiger/trunk/include/database/Postgres8.php new file mode 100644 index 00000000..0464465f --- /dev/null +++ b/oss/vtiger/trunk/include/database/Postgres8.php @@ -0,0 +1,228 @@ +info( "fixPostgresQuery: ".$query); + + // If we already have an order or group cluase separate ist for later use + if( stripos($queryRecord,'GROUP BY') > 0) + { + $groupClause = substr($queryRecord, stripos($queryRecord,'GROUP BY')+strlen('GROUP BY'), strlen($queryRecord)); + if( stripos($groupClause,'ORDER BY') > 0) + { + $orderClause = substr($groupClause, stripos($groupClause,'ORDER BY'), strlen($groupClause)); + $groupClause = substr($groupClause, 0, stripos($groupClause,'ORDER BY')); + } + $queryRecord = substr($queryRecord, 0, stripos($queryRecord,'GROUP BY')); + } + + if( stripos($queryRecord,'ORDER BY') > 0) + { + $orderClause = substr($queryRecord, stripos($queryRecord,'ORDER BY'), strlen($queryRecord)); + $queryRecord = substr($queryRecord, 0, stripos($queryRecord,'ORDER BY')); + } + + // Construkt the privateGroupList from the filed list by separating combined + // record.field entries + $privateGroupList = array(); + $token = strtok( $queryFields, ", () "); + while( $token !== false) { + if( strpos( $token, ".") !== false) + array_push( $privateGroupList, $token); + $token = strtok( ", () "); + } + sort( $privateGroupList); + $groupFields = ""; + $last = ""; + for( $i = 0; $i < count($privateGroupList); $i++) { + if( $last != $privateGroupList[$i]) + if( $groupFields == "") + $groupFields = $privateGroupList[$i]; + else + $groupFields .= ",".$privateGroupList[$i]; + $last = $privateGroupList[$i]; + } + + // Rebuild the query + $query = "SELECT ".$queryFields.$queryRecord; + if( $groupClause != "" ) + $groupClause =$groupClause.",".$groupFields; + else + $groupClause =$groupFields; + $query .= expandStar($groupClause,$log)." ".$orderClause; + + if( $debug) + $log->info( "fixPostgresQuery result: ".$query); + + return( $query); +} + +// Postgres8 will not accept a "tablename.*" entry in the GROUP BY clause +function expandStar($fieldlist,$log) +{ + $expanded=""; + $field = strtok( $fieldlist, ","); + while( $field != "") + { + //remove leading and trailing spaces + $field = trim( $field); + + //still spaces in the field indicate a complex structure + if( strpos( $field, " ") == 0) + { + + //locate table- and fieldname + $pos = strpos( $field, "."); + if( $pos > 0) + { + $table = substr( $field, 0, $pos); + $subfield = substr( $field, $pos+1, strlen($field)-$pos); + + //do we need to expand? + if( $subfield == "*") + $field = expandRecord($table,$log); + } + + //add the propably expanded field to the querylist + if( $expanded == "") + $expanded = $field; + else + $expanded .= ",".$field; + } + + //next field + $field = strtok(","); + } + if($expanded!= '') + $expanded = " GROUP BY ". trim($expanded, ","); + //return the expanded fieldlist + return( $expanded); +} + +//return an expanded table field list +function expandRecord($table,$log) +{ + $result = ""; + $log->info( "Debug: expandRecord"); + $subfields = array(); + + //vtiger_products table + if( $table == "vtiger_products" ) + $subfields = array ( "productid", "productname", "productcode", "productcategory", "manufacturer", "qty_per_unit", "unit_price", "weight", "pack_size", "sales_start_date", "sales_end_date", "start_date", "expiry_date", "cost_factor", "commissionrate", "commissionmethod", "discontinued", "usageunit", "handler", "currency", "reorderlevel", "website", "taxclass", "mfr_part_no", "vendor_part_no", "serialno", "qtyinstock", "productsheet", "qtyindemand", "glacct", "vendor_id", "imagename"); + //$subfields = array ( "productid", "productname", "productcode", "productcategory", "manufacturer", "qty_per_unit", "unit_price", "weight", "pack_size", "sales_start_date", "sales_end_date", "start_date", "expiry_date", "cost_factor", "commissionrate", "commissionmethod", "discontinued", "usageunit", "handler", "contactid", "currency", "reorderlevel", "website", "taxclass", "mfr_part_no", "vendor_part_no", "serialno", "qtyinstock", "productsheet", "qtyindemand", "glacct", "vendor_id", "imagename" ); + + //vtiger_activity table + elseif( $table == "vtiger_activity") + $subfields = array ( "activityid", "subject", "semodule", "activitytype", "date_start", "due_date", "time_start", "time_end", "sendnotification", "duration_hours", "duration_minutes", "status", "eventstatus", "priority", "location", "notime", "visibility", "recurringtype" ); + + //vtiger_notes table + elseif( $table == "vtiger_notes") + $subfields = array ( "notesid", "contact_id", "title", "filename", "notecontent"); + + //vtiger_faq table + elseif( $table == "vtiger_faq") + $subfields = array ( "id", "product_id", "question", "answer", "category", "status"); + + //vtiger_profile2field + elseif( $table == "vtiger_profile2field") + $subfields = array ( "profileid", "tabid", "fieldid", "visible", "readonly"); + + //vtiger_field + elseif( $table == "vtiger_field") + $subfields = array ( "tabid", "fieldid", "columnname", "tablename", "generatedtype", "uitype", "fieldname", "fieldlabel", "readonly", "presence", "selected", "maximumlength", "sequence", "block", "displaytype", "typeofdata", "quickcreate", "quickcreatesequence", "info_type"); + + //vtiger_producttaxrel + elseif( $table == "vtiger_producttaxrel") + $subfields = array ( "productid", "taxid", "taxpercentage"); + + //vtiger_inventorytaxinfo + elseif( $table == "vtiger_inventorytaxinfo") + $subfields = array ( "taxid", "taxname", "taxlabel", "percentage", "deleted"); + + //vtiger_role2picklist + elseif( $table == "vtiger_role2picklist") + $subfields = array ( "roleid", "picklistid", "sortid"); + + //vtiger_contactdetails + elseif( $table == "vtiger_contactdetails") + $subfields = array( "lastname", "contactid", "accountid", "salutation", "firstname", "email", "phone", "mobile", "title", "department", "fax", "reportsto", "training", "usertype", "contacttype", "otheremail", "yahooid", "donotcall", "emailoptout", "imagename", "reference", "notify_owner"); + + //vtiger_quotes + elseif( $table == "vtiger_quotes") + $subfields = array( "quoteid", "subject", "potentialid", "quotestage", "validtill", "contactid", "currency", "subtotal", "carrier", "shipping", "inventorymanager", "type", "adjustment", "total", "taxtype", "discount_percent", "discount_amount", "s_h_amount", "accountid", "terms_conditions"); + + //vtiger_crmentity + elseif( $table == "vtiger_crmentity") + $subfields = array("crmid", "smcreatorid", "smownerid", "modifiedby", "setype", "description", "createdtime", "modifiedtime", "viewedtime", "status", "version", "presence", "deleted"); + + //vtiger_salesorder + elseif( $table == "vtiger_salesorder") + $subfields = array("salesorderid", "subject", "potentialid", "customerno", "quoteid", "vendorterms", "contactid", "vendorid", "duedate", "carrier", "pending", "type", "adjustment", "salescommission", "exciseduty","total", "subtotal", "taxtype", "discount_percent", "discount_amount", "s_h_amount", "accountid", "terms_conditions", "purchaseorder", "sostatus"); + + //vtiger_invoice + elseif( $table == "vtiger_invoice") + $subfields = array("invoiceid", "subject", "salesorderid","customerno","contactid", "notes", "invoicedate", "duedate", "invoiceterms", "type", "adjustment","salescommission","exciseduty", "subtotal","total", "taxtype","discount_percent", "discount_amount", "s_h_amount","shipping", "accountid", "terms_conditions","purchaseorder","invoicestatus","invoice_no"); + + //vtiger_seactivityrel + elseif( $table == "vtiger_seactivityrel") + $subfields = array("crmid", "activityid"); + + //vtiger_cntactivityrel + elseif( $table == "vtiger_cntactivityrel") + $subfields = array("contactid", "activityid"); + + //vtiger_purchaseorder + elseif( $table == "vtiger_purchaseorder") + $subfields = array("purchaseorderid", "subject", "quoteid", "vendorid", "requisition_no", "tracking_no", "contactid", "duedate", "carrier", "type", "adjustment", "salescommission", "exciseduty", "total", "subtotal", "taxtype", "discount_percent","discount_amount", "s_h_amount", "terms_conditions", "postatus"); + + //vtiger_leaddetails + elseif( $table == "vtiger_leaddetails") + $subfields = array("leadid", "email", "interest", "firstname", "salutation", "lastname", "company", "annualrevenue", "industry", "campaign", "rating", "leadstatus", "leadsource", "converted", "designation", "space", "comments", "priority", "demorequest", "partnercontact", "productversion", "product", "maildate", "nextstepdate", "fundingsituation", "purpose", "evaluationstatus", "transferdate", "revenuetype", "noofemployees", "yahooid", "assignleadchk" ); + + //vtiger_campaignleadrel + elseif( $table == "vtiger_campaignleadrel") + $subfields = array("campaignid", "leadid"); + + //vtiger_pricebook + elseif( $table == "vtiger_pricebook") + $subfields = array("pricebookid", "bookname","active","description"); + + //fields of the requested array still undefined + else + $log->info("function expandRecord: please add structural information for table '".$table."'"); + + //construct an entity string + for( $i=0; $i 0) + $result = substr( $result, 0, strlen( $result) -1); + + //return out new string + return( $result); +} +?> diff --git a/oss/vtiger/trunk/include/db_backup/DatabaseBackup.php b/oss/vtiger/trunk/include/db_backup/DatabaseBackup.php new file mode 100644 index 00000000..b39857ca --- /dev/null +++ b/oss/vtiger/trunk/include/db_backup/DatabaseBackup.php @@ -0,0 +1,317 @@ +'Source database connect failed', + 'DestConnectFailed'=>'Destination database connect failed', + 'TableListFetchError'=>'Failed to get Table List for database', + 'SqlExecutionError'=>'Execution of following query failed', +); + +class DatabaseConfig{ + private $hostName = null; + private $username = null; + private $password = null; + private $dbName = null; + private $rootUsername = null; + private $rootPassword = null; + function DatabaseConfig($dbserver, $username, $password,$dbName, $rootusername='', $rootpassword=''){ + $this->hostName = $dbserver; + $this->username = $username; + $this->password = $password; + $this->dbName = $dbName; + $this->rootUsername = $rootusername; + $this->rootPassword = $rootpassword; + } + + function getHostName(){ + return $this->hostName; + } + + function getUsername(){ + return $this->username; + } + + function getPassword(){ + return $this->password; + } + + function getRootUsername(){ + return $this->rootUsername; + } + + function getRootPassword(){ + return $this->rootPassword; + } + + function getDatabaseName(){ + return $this->dbName; + } + +} + +class DatabaseBackupException extends Exception{ + public $code; + public $message; + + function DatabaseBackupException($errCode,$msg){ + $this->code = $errCode; + $this->message = $msg; + } +} + +class DatabaseErrorCode{ + public static $DB_CONNECT_ERROR = 'CONNECT_ERROR'; + public static $TABLE_NAME_ERROR = 'TABLE_LIST_FETCH_ERROR'; + public static $SQL_EXECUTION_ERROR = 'SQL_EXECUTION_ERROR'; +} + +class DatabaseBackup { + private $sourceConfig = null; + private $destinationConfig = null; + private $dbType = null; + private $sourceCon = null; + private $destCon = null; + private static $langString = null; + private $downloadMode = null; + private $createTarget = null; + private $supportUTF8 = null; + function DatabaseBackup($dbType='mysql',$createTarget=false,$utf=true){ + $this->dbType = strtolower($dbType); + if(!is_array(DatabaseBackup::$langString)){ + DatabaseBackup::$langString = getLanguageStrings(); + } + $this->downloadMode = false; + $this->createTarget = $createTarget; + $this->supportUTF8 = $utf; + } + + function setSourceConfig($sourceConfig){ + $this->sourceConfig = $sourceConfig; + $this->initSourceConnection(); + } + + function setDestinationConfig($destinationConfig){ + $this->destinationConfig = $destinationConfig; + $this->initDestinationConnection(); + } + + function enableDownloadMode(){ + $this->downloadMode = true; + } + + function isDownloadMode(){ + return $this->downloadMode; + } + + function isUTF8SupportEnabled() { + return $this->supportUTF8; + } + + function getSourceConnection(){ + return $this->sourceCon; + } + + function getDestinationConnection(){ + return $this->destCon; + } + + function initSourceConnection(){ + $this->sourceCon = &NewADOConnection($this->dbType); + $ok = $this->sourceCon->NConnect($this->sourceConfig->getHostName(),$this->sourceConfig->getUserName(), + $this->sourceConfig->getPassword(),$this->sourceConfig->getDatabaseName()); + if(!$ok){ + throw new DatabaseBackupException(DatabaseErrorCode::$DB_CONNECT_ERROR, + DatabaseBackup::$langString['SourceConnectFailed']); + } + $this->sourceCon->_Execute("SET NAMES 'utf8'",false); + $result = $this->sourceCon->_Execute("SET interactive_timeout=28800",false); + $result = $this->sourceCon->_Execute("SET wait_timeout=28800",false); + $result = $this->sourceCon->_Execute("SET net_write_timeout=900",false); + $result = $this->sourceCon->_Execute("SET net_read_timeout=900",false); + } + + function initDestinationConnection(){ + $this->destCon = &NewADOConnection($this->dbType); + if($this->createTarget){ + $this->createTargetDB(); + } + $ok = $this->destCon->NConnect($this->destinationConfig->getHostName(),$this->destinationConfig->getUserName(), + $this->destinationConfig->getPassword(),$this->destinationConfig->getDatabaseName()); + if(!$ok){ + throw new DatabaseBackupException(DatabaseErrorCode::$DB_CONNECT_ERROR, + DatabaseBackup::$langString['DestConnectFailed']); + } + $result = $this->destCon->_Execute("SET interactive_timeout=28800",false); + $result = $this->destCon->_Execute("SET wait_timeout=28800",false); + $result = $this->destCon->_Execute("SET net_write_timeout=900",false); + } + + function createTargetDB(){ + if(!$this->isDownloadMode()){ + if($this->dbType == 'mysql'){ + $ok = $this->destCon->NConnect($this->destinationConfig->getHostName(),$this->destinationConfig->getRootUserName(), + $this->destinationConfig->getRootPassword()); + if(!$ok){ + throw new DatabaseBackupException(DatabaseErrorCode::$DB_CONNECT_ERROR, + DatabaseBackup::$langString['DestConnectFailed']); + } + // Drop database if already exists + $sql = "drop database IF EXISTS ".$this->destinationConfig->getDatabaseName(); + $result = $this->destCon->Execute($sql); + $this->checkError($result,$sql); + + $sql = 'create database '.$this->destinationConfig->getDatabaseName(); + if( $this->supportUTF8 == true){ + $sql .= " default character set utf8 default collate utf8_general_ci"; + } + $result = $this->destCon->Execute($sql); + $this->checkError($result,$sql); + $this->destCon->Close(); + $this->destCon = &NewADOConnection($this->dbType); + } + } + } + + function initBackup(){ + if(!$this->isDownloadMode()){ + $sql = "SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0"; + $result = $this->destCon->_Execute($sql,false); + $this->checkError($result,$sql); + $sql = "SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO';"; + $result = $this->destCon->_Execute($sql,false); + $this->checkError($result,$sql); + $sql = 'SET NAMES utf8'; + $result = $this->destCon->_Execute($sql,false); + $this->checkError($result,$sql); + return; + }else{ + $this->writeLine('-- Dump generated by vtigerCRM'); + $this->writeLine('-- Date: ' . date("D, M j, G:i:s T Y")); + $this->writeLine('-- HOST: ' . $this->sourceConfig->getHostName(). + ' Database: '.$this->sourceConfig->getDatabaseName()); + $this->writeLine("-- ----------------------------------"); + $this->writeLine(""); + + $this->writeLine("/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;"); + $this->writeLine("/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;"); + $this->writeLine("/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;"); + $this->writeLine("/*!40101 SET NAMES utf8 */;"); + $this->writeLine("/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;"); + $this->writeLine("/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;"); + $this->writeLine("/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;"); + $this->writeLine("/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;"); + } + } + + function writeLine($string){ + echo $string,"\n"; + } + + function finalizeBackup(){ + if(!$this->isDownloadMode()){ + $sql = "SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS"; + $result = $this->destCon->_Execute($sql,false); + $this->checkError($result,$sql); + $sql = "SET SQL_MODE=@OLD_SQL_MODE;"; + $result = $this->destCon->_Execute($sql,false); + $this->checkError($result,$sql); + return; + }else{ + $this->writeLine("/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;"); + $this->writeLine("/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;"); + $this->writeLine("/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;"); + $this->writeLine("/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;"); + $this->writeLine("/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;"); + $this->writeLine("/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;"); + $this->writeLine("/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;"); + $this->writeLine("-- DONE"); + } + } + + function processTableCreate($tableName,$sql){ + if(!$this->isDownloadMode()){ + $result = $this->destCon->_Execute($sql,false); + $this->checkError($result,$sql); + }else{ + $this->writeLine(""); + $this->writeLine("--"); + $this->writeLine("-- Table structure for table $tableName"); + $this->writeLine("--"); + $this->writeLine(""); + $this->writeLine("DROP TABLE IF EXISTS $tableName;"); + $this->writeLine($sql.';'); + $this->writeLine(""); + $this->writeLine("--"); + $this->writeLine("-- Dumping data for table $tableName"); + $this->writeLine("--"); + $this->writeLine(""); + } + } + + function processStatement($sql){ + if(!$this->isDownloadMode()){ + $result = $this->destCon->_Execute($sql,false); + $this->checkError($result,$sql); + }else{ + $this->writeLine($sql.';'); + } + } + + function checkError($result,$sql){ + if($result === false){ + throw new DatabaseBackupException(DatabaseErrorCode::$SQL_EXECUTION_ERROR, + DatabaseBackup::$langString['SqlExecutionError'].' '.$sql); + } + } + + function backup(){ + $this->initBackup(); + set_time_limit(0); + $tableNameList = $this->sourceCon->MetaTables('TABLES'); + if($tableNameList === false){ + throw new DatabaseBackupException(DatabaseErrorCode::$TABLE_NAME_ERROR, + DatabaseBackup::$langString['TableListFetchError']); + } + foreach ($tableNameList as $tableName) { + $sql = $this->getTableCreateStatement($this->sourceCon,$tableName); + $this->processTableCreate($tableName,$sql); + $sql = "select * from $tableName"; + $result = $this->sourceCon->_Execute($sql,false); + $this->checkError($result,$sql); + while(!$result->EOF){ + $row = $result->GetRowAssoc(2); + $sql = $this->sourceCon->GetInsertSQL($tableName,$row); + $this->processStatement($sql); + $result->MoveNext(); + } + } + $this->finalizeBackup(); + } + + function getTableCreateStatement($con, $tableName){ + if($this->dbType == 'mysql'){ + $sql = "show create table $tableName"; + $result = $con->_Execute($sql,false); + $this->checkError($result,$sql.' '.$con->ErrorMsg().' '.$con->ErrorNo()); + $data = $result->FetchRow(); + return $data[1]; + } + } + +} + +function getLanguageStrings(){ + global $langString; + return $langString; +} + +?> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/db_backup/backup.php b/oss/vtiger/trunk/include/db_backup/backup.php new file mode 100644 index 00000000..ec7f340f --- /dev/null +++ b/oss/vtiger/trunk/include/db_backup/backup.php @@ -0,0 +1,351 @@ +debug("Entering save_structure(".$filename.",".$root_directory.") method ..."); + + $dbdump = new DatabaseDump(dbserver, dbuser, dbpass); + $dumpfile = $root_directory.'/'.$filename; + $dbdump->save(dbname, $dumpfile) ; + $log->debug("Exiting save_structure method ..."); +} + +/** + * DatabaseDump will save the dump of database to the file specified. + * + * The dump file contains series of SQL statements (with some meta information) + * generated similar to mysqldump command. + * + * To restore back the dump you can use the 'source' command in sql. + * Like: + * mysql> create database dbname; + * mysql> use dbname; + * mysql> source sql_dump_file; + * + * @author Prasad + */ +class DatabaseDump { + private $fhandle; + function DatabaseDump($dbserver, $username, $password) { + mysql_connect($dbserver, $username, $password); + } + function save($database, $filename) { + // Connect to database + $db = mysql_select_db($database); + $db_charset = mysql_fetch_assoc(mysql_query("SHOW variables LIKe'character_set_database'")); + if($db_charset['Value']=='utf8'){ + mysql_query("SET NAMES 'utf8'"); + } + if(empty($db)) { + return; + } + $this->file_open($filename); + + // Write some information regarding database dump and the time first. + $this->writeln("SET NAMES 'utf8';"); + $this->writeln("-- $database database dump"); + $this->writeln("-- Date: " . date("D, M j, G:i:s T Y")); + $this->writeln("-- ----------------------------------"); + $this->writeln(""); + + // Meta information which helps to import into mysql database. + $this->writeln("SET FOREIGN_KEY_CHECKS=0;"); + $this->writeln("SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';"); + $this->writeln(""); + + // Get all table names from database + $tcount = 0; + $trs = mysql_list_tables($database); + for($tindex = 0; $tindex < mysql_num_rows($trs); $tindex++) { + $table = mysql_tablename($trs, $tindex); + if(!empty($table)) { + $tables[$tcount] = mysql_tablename($trs, $tindex); + $tcount++; + } + } + + // List tables + $dump = ''; + for($tindex = 0; $tindex < count($tables); $tindex++) { + // Table Name + $table = $tables[$tindex]; + + $table_create_rs = mysql_query("SHOW CREATE TABLE `$table`"); + $table_create_rows = mysql_fetch_array($table_create_rs); + $table_create_sql = $table_create_rows[1]; + + // Our parser used for reading the dump file is very basic + // hence we will need to remove the new lines + $table_create_sql = str_replace("\n","",$table_create_sql); + + // Our parser used for reading the dump file is very basic + // hence we will need to remove the new lines + $table_create_sql = str_replace("\n","",$table_create_sql); + + // Write table create statement + $this->writeln(""); + $this->writeln("--"); + $this->writeln("-- Table structure for table `$table` "); + $this->writeln("--"); + $this->writeln(""); + $this->writeln("DROP TABLE IF EXISTS `$table`;"); + $this->writeln($table_create_sql . ';'); + $this->writeln(""); + + // Write data + $this->writeln("--"); + $this->writeln("-- Dumping data for table `$table` "); + $this->writeln("--"); + $this->writeln(""); + + $table_query = mysql_query("SELECT * FROM `$table`"); + $num_fields = mysql_num_fields($table_query); + while($fetch_row = mysql_fetch_array($table_query)) { + $insert_sql = "INSERT INTO `$table` VALUES("; + for($n = 1; $n <= $num_fields; $n++) { + $m = $n -1; + $field_value = $fetch_row[$m]; + $field_value = str_replace('\"', '"', mysql_escape_string($field_value)); + $insert_sql .= "'". $field_value . "', "; + } + $insert_sql = substr($insert_sql,0,-2); + $insert_sql .= ");"; + + if($insert_sql != "") { + $this->writeln($insert_sql); + } + } + } + // Meta information reset to original state. + $this->writeln("SET FOREIGN_KEY_CHECKS=0;"); + + $this->file_close(); + } + function file_open($filename) { $this->fhandle = fopen($filename, "w+"); } + function file_close() { fclose($this->fhandle); } + function write($string) { fprintf($this->fhandle, "%s", $string); } + function writeln($string) { fprintf($this->fhandle, "%s\r\n", $string); } +}; + + +class createZip { + + public $compressedData = array(); + public $centralDirectory = array(); // central directory + public $endOfCentralDirectory = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record + public $oldOffset = 0; + + /** + * Function to create the directory where the file(s) will be unzipped + * + * @param $directoryName string + * + */ + + public function addDirectory($directoryName) { + $directoryName = str_replace("\\", "/", $directoryName); + + $feedArrayRow = "\x50\x4b\x03\x04"; + $feedArrayRow .= "\x0a\x00"; + $feedArrayRow .= "\x00\x00"; + $feedArrayRow .= "\x00\x00"; + $feedArrayRow .= "\x00\x00\x00\x00"; + + $feedArrayRow .= pack("V",0); + $feedArrayRow .= pack("V",0); + $feedArrayRow .= pack("V",0); + $feedArrayRow .= pack("v", strlen($directoryName) ); + $feedArrayRow .= pack("v", 0 ); + $feedArrayRow .= $directoryName; + + $feedArrayRow .= pack("V",0); + $feedArrayRow .= pack("V",0); + $feedArrayRow .= pack("V",0); + + $this -> compressedData[] = $feedArrayRow; + + $newOffset = strlen(implode("", $this->compressedData)); + + $addCentralRecord = "\x50\x4b\x01\x02"; + $addCentralRecord .="\x00\x00"; + $addCentralRecord .="\x0a\x00"; + $addCentralRecord .="\x00\x00"; + $addCentralRecord .="\x00\x00"; + $addCentralRecord .="\x00\x00\x00\x00"; + $addCentralRecord .= pack("V",0); + $addCentralRecord .= pack("V",0); + $addCentralRecord .= pack("V",0); + $addCentralRecord .= pack("v", strlen($directoryName) ); + $addCentralRecord .= pack("v", 0 ); + $addCentralRecord .= pack("v", 0 ); + $addCentralRecord .= pack("v", 0 ); + $addCentralRecord .= pack("v", 0 ); + $ext = "\x00\x00\x10\x00"; + $ext = "\xff\xff\xff\xff"; + $addCentralRecord .= pack("V", 16 ); + + $addCentralRecord .= pack("V", $this -> oldOffset ); + $this -> oldOffset = $newOffset; + + $addCentralRecord .= $directoryName; + + $this -> centralDirectory[] = $addCentralRecord; + } + + /** + * Function to add file(s) to the specified directory in the archive + * + * @param $directoryName string + * + */ + + public function addFile($data, $directoryName) { + + $directoryName = str_replace("\\", "/", $directoryName); + + $feedArrayRow = "\x50\x4b\x03\x04"; + $feedArrayRow .= "\x14\x00"; + $feedArrayRow .= "\x00\x00"; + $feedArrayRow .= "\x08\x00"; + $feedArrayRow .= "\x00\x00\x00\x00"; + + $uncompressedLength = strlen($data); + $compression = crc32($data); + $gzCompressedData = gzcompress($data); + $gzCompressedData = substr( substr($gzCompressedData, 0, strlen($gzCompressedData) - 4), 2); + $compressedLength = strlen($gzCompressedData); + $feedArrayRow .= pack("V",$compression); + $feedArrayRow .= pack("V",$compressedLength); + $feedArrayRow .= pack("V",$uncompressedLength); + $feedArrayRow .= pack("v", strlen($directoryName) ); + $feedArrayRow .= pack("v", 0 ); + $feedArrayRow .= $directoryName; + + $feedArrayRow .= $gzCompressedData; + + $feedArrayRow .= pack("V",$compression); + $feedArrayRow .= pack("V",$compressedLength); + $feedArrayRow .= pack("V",$uncompressedLength); + + $this -> compressedData[] = $feedArrayRow; + + $newOffset = strlen(implode("", $this->compressedData)); + + $addCentralRecord = "\x50\x4b\x01\x02"; + $addCentralRecord .="\x00\x00"; + $addCentralRecord .="\x14\x00"; + $addCentralRecord .="\x00\x00"; + $addCentralRecord .="\x08\x00"; + $addCentralRecord .="\x00\x00\x00\x00"; + $addCentralRecord .= pack("V",$compression); + $addCentralRecord .= pack("V",$compressedLength); + $addCentralRecord .= pack("V",$uncompressedLength); + $addCentralRecord .= pack("v", strlen($directoryName) ); + $addCentralRecord .= pack("v", 0 ); + $addCentralRecord .= pack("v", 0 ); + $addCentralRecord .= pack("v", 0 ); + $addCentralRecord .= pack("v", 0 ); + $addCentralRecord .= pack("V", 32 ); + + $addCentralRecord .= pack("V", $this -> oldOffset ); + $this -> oldOffset = $newOffset; + + $addCentralRecord .= $directoryName; + + $this -> centralDirectory[] = $addCentralRecord; + } + + /** + * Fucntion to return the zip file + * + * @return zipfile (archive) + */ + + public function getZippedfile() { + + $data = implode("", $this -> compressedData); + $controlDirectory = implode("", $this -> centralDirectory); + + return + $data. + $controlDirectory. + $this -> endOfCentralDirectory. + pack("v", sizeof($this -> centralDirectory)). + pack("v", sizeof($this -> centralDirectory)). + pack("V", strlen($controlDirectory)). + pack("V", strlen($data)). + "\x00\x00"; + } + + /** + * + * Function to force the download of the archive as soon as it is created + * + * @param archiveName string - name of the created archive file + */ + + public function forceDownload($archiveName) { + $headerInfo = ''; + + if(ini_get('zlib.output_compression')) { + ini_set('zlib.output_compression', 'Off'); + } + + // Security checks + if( $archiveName == "" ) { + echo "Public Photo Directory - Download
ERROR: The download file was NOT SPECIFIED."; + exit; + } + elseif ( ! file_exists( $archiveName ) ) { + echo "Public Photo Directory - Download
ERROR: File not found."; + exit; + } + + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); + header("Cache-Control: private",false); + header("Content-Type: application/zip"); + header("Content-Disposition: attachment; filename=".basename($archiveName).";" ); + header("Content-Transfer-Encoding: binary"); + header("Content-Length: ".filesize($archiveName)); + readfile("$archiveName"); + + } + +} + +class createDirZip extends createZip { + function get_files_from_folder($directory, $put_into) { + if ($handle = @opendir($directory)) { + while (false != ($file = readdir($handle))) { + if (is_file($directory.$file)) { + $fileContents = file_get_contents($directory.$file); + $this->addFile($fileContents, $put_into.$file); + } elseif ($file != '.' and $file != '..' and is_dir($directory.$file)) { + $this->addDirectory($put_into.$file.'/'); + $this->get_files_from_folder($directory.$file.'/', $put_into.$file.'/'); + } + } + } + @closedir($handle); + } +} +?> diff --git a/oss/vtiger/trunk/include/db_backup/ftp.php b/oss/vtiger/trunk/include/db_backup/ftp.php new file mode 100644 index 00000000..1caea866 --- /dev/null +++ b/oss/vtiger/trunk/include/db_backup/ftp.php @@ -0,0 +1,65 @@ +debug("Entering ftpBackupFile(".$source_file.", ".$ftpserver.", ".$ftpuser.", ".$ftppassword.") method ..."); + // set up basic connection + $conn_id = @ftp_connect($ftpserver); + if(!$conn_id) + { + $log->debug("Exiting ftpBackupFile method ..."); + return; + } + + + // login with username and password + + $login_result = @ftp_login($conn_id, $ftpuser, $ftppassword); + + if(!$login_result) + { + ftp_close($conn_id); + $log->debug("Exiting ftpBackupFile method ..."); + return; + } + + // check connection + /*if ((!$conn_id) || (!$login_result)) { + echo "FTP connection has failed!"; + echo "Attempted to connect to $ftp_server for user $ftp_user_name"; + exit; + } else { + echo "Connected to $ftp_server, for user $ftp_user_name"; + } + */ + + // upload the file + $destination_file=$source_file; + $upload = @ftp_put($conn_id, $destination_file, $source_file, FTP_BINARY); + + // check upload status + if (!$upload) { + ftp_close($conn_id); + $log->debug("Exiting ftpBackupFile method ..."); + return; + } + /* + else { + echo "Uploaded $source_file to $ftp_server as $destination_file"; + }*/ + + // close the FTP stream + ftp_close($conn_id); + $log->debug("Exiting ftpBackupFile method ..."); +} +?> diff --git a/oss/vtiger/trunk/include/events/SqlResultIterator.inc b/oss/vtiger/trunk/include/events/SqlResultIterator.inc new file mode 100644 index 00000000..bb9362ac --- /dev/null +++ b/oss/vtiger/trunk/include/events/SqlResultIterator.inc @@ -0,0 +1,92 @@ +result = $result; + $this->adb = $adb; + $this->pos = 0; + } + + public function rewind(){ + $this->pos = 0; + } + + function valid(){ + $adb = $this->adb; + return $this->pos < $adb->num_rows($this->result); + } + + public function next(){ + $this->pos+=1; + } + + public function current(){ + $adb = $this->adb; + $data = $adb->raw_query_result_rowdata($this->result, $this->pos); + return new SqlResultIteratorRow($data); + } + + public function key(){ + return $this->pos; + } + + + /** + * Return the contents of the resultset as an array. Destroys a running iterator's state. + * + * This method will reset the iterator using the rewind method. + * + * $copyFields specify which fields of the result to copy to the array. + * If not specified the function will return values for all the fields. + */ + function toArray($copyFields=null){ + $adb = $this->adb; + $this->rewind(); + + if($copyFields===null){ + $columnData = $adb->getFieldsDefinition($this->result); + $columnNames = array(); + foreach($columnData as $column){ + $columnNames[]=$column->name; + } + $copyFields = $columnNames; + } + + $arr=array(); + foreach($this as $row){ + $rowArr = array(); + foreach($copyFields as $name){ + $rowArr[$name]=$row->$name; + } + $arr[]=$rowArr; + } + return $arr; + $this->rewind(); + } + } + + class SqlResultIteratorRow{ + function __construct($data){ + $this->data = $data; + } + + function get($column){ + return $this->data[$column]; + } + + function __get($column){ + return $this->get($column); + } + + } + + +?> diff --git a/oss/vtiger/trunk/include/events/VTEntityData.inc b/oss/vtiger/trunk/include/events/VTEntityData.inc new file mode 100644 index 00000000..d706eebc --- /dev/null +++ b/oss/vtiger/trunk/include/events/VTEntityData.inc @@ -0,0 +1,125 @@ +entityId = $entityId; + $result = $adb->pquery("select setype from vtiger_crmentity where crmid=?", array($entityId)); + $setype = $adb->query_result($result,0,"setype"); + $obj->moduleName = $setype; + + require_once('data/CRMEntity.php'); + $focus = CRMEntity::getInstance($setype); + + $focus->retrieve_entity_info($entityId, $setype); + $focus->id = $entityId; + $obj->isNew = false; + $obj->focus = $focus; + return $obj; + } + + + /** + * Get an entity data object from a crmentity object + * + * @param $crmEntity The CRMEntity instance. + * @return The new entity data object. + */ + static function fromCRMEntity($crmEntity){ + $obj = new VTEntityData(); + $obj->focus = $crmEntity; + $obj->isNew = !(isset($crmEntity->id) && $crmEntity->id != null); + return $obj; + } + + /** + * Get the data from the entity object as an array. + * + * @return An array representation of the module data. + */ + function getData(){ + return $this->focus->column_fields; + } + + /** + * Get the entity id. + * + * @return The entity id. + */ + function getId(){ + return $this->focus->id; + } + + /** + * Get the name of the module represented by the entity data object. + * + * @return The module name. + */ + function getModuleName(){ + $className = get_class($this->focus); + $importModuleMapping = Array( + "ImportLead"=>"Leads", + "ImportAccount"=>"Accounts", + "ImportContact"=>"Contacts", + "ImportOpportunity"=>"Potentials", + "ImportProduct"=>"Products", + "ImportTicket"=>"HelpDesk", + "ImportVendors"=>"Vendors" + ); + $moduleName = $className; + if(array_key_exists($className, $importModuleMapping)){ + $moduleName = $importModuleMapping[$className]; + } + return $moduleName; + } + + function get($fieldName){ + return $this->focus->column_fields[$fieldName]; + } + + function set($fieldName, $value){ + $data = $this->focus->column_fields[$fieldName] = $value; + } + + /** + * Check whether the object is stored on the database. + * + * @return True if the object is saved false otherwiser. + */ + function isSaved(){ + return isset($this->focus->id); + } + + + /** + * Check wether the obkect is new. + * + * @return True if the object is new, false otherwise. + */ + function isNew(){ + return $this->isNew; + } + + } + +?> diff --git a/oss/vtiger/trunk/include/events/VTEntityType.inc b/oss/vtiger/trunk/include/events/VTEntityType.inc new file mode 100644 index 00000000..81339dc3 --- /dev/null +++ b/oss/vtiger/trunk/include/events/VTEntityType.inc @@ -0,0 +1,87 @@ +moduleName=$setype; + require_once("modules/".$setype."/".$setype.".php"); + $result = $adb->pquery("select tabid from vtiger_tab where name=?", + array($setype)); + $tabId = $adb->query_result($result,0,"tabid"); + $this->tabId = $tabId; + $this->adb = $adb; + } + + function getTabId(){ + return $this->tabId; + } + + function getModuleName(){ + return $this->moduleName; + } + + function getFieldNames(){ + $adb = $this->adb; + $arr = array(); + $result = $adb->pquery("select fieldname from vtiger_field where tabid=? and vtiger_field.presence in (0,2)", + array($this->getTabId())); + $it = new SQLResultIterator($adb, $result); + foreach($it as $row){ + $arr[] = $row->fieldname; + } + return $arr; + } + + function getFieldType($fieldName){ + $adb = $this->adb; + $result = $adb->pquery("select * from vtiger_field where fieldname=? and tabid=? and vtiger_field.presence in (0,2)", + array($fieldName, $this->tabId)); + $uitype = $adb->query_result($result,0,"uitype"); + $fieldType = new VTFieldType(); + if(in_array($uitype, array(50, 51, 73))){ + $fieldType->type = "Related"; + $fieldType->relatedTo = "Accounts"; + }else if($uitype == 71){ + $fieldType->type = "Number"; + }else{ + $fieldType->type = "String"; + } + return $fieldType; + } + + function getFieldTypes(){ + $adb = $this->adb; + $fieldNames = $this->getFieldNames(); + $fieldTypes = array(); + foreach($fieldNames as $fieldName){ + $fieldTypes[$fieldName]=$this->getFieldType($fieldName); + } + return $fieldTypes; + } + + +} + +class VTFieldType{ + function toArray(){ + $ro = new ReflectionObject($this); + $props = $ro->getProperties(); + $arr = array(); + foreach($props as $prop){ + $arr[$prop->getName()]=$prop->getValue($this); + } + return $arr; + } + +} + +?> diff --git a/oss/vtiger/trunk/include/events/VTEventCondition.php b/oss/vtiger/trunk/include/events/VTEventCondition.php new file mode 100644 index 00000000..e1676640 --- /dev/null +++ b/oss/vtiger/trunk/include/events/VTEventCondition.php @@ -0,0 +1,82 @@ +getParser($expr); + $this->expr = $parser->statement(); + }else{ + $this->expr = null; + } + } + + + function test($obj){ + $this->data = $obj; + if($this->expr==null){ + return true; + }else{ + return $this->evaluate($this->expr); + } + } + + private function getParser($expr){ + $ass = new ANTLRStringStream($expr); + $lex = new VTEventConditionParserLexer($ass); + $cts = new CommonTokenStream($lex); + $tap = new VTEventConditionParserParser($cts); + return $tap; + } + + + private function evaluate($expr){ + if(is_array($expr)){ + $oper = $expr[0]; + if($oper=='.'){ + $out = $this->data; + $syms = array_slice($expr, 1); + foreach($syms as $sym){ + $out = $this->get($out, $sym->name); + } + return $out; + }else{ + $evaled = array_map(array($this, 'evaluate'), array_slice($expr, 1)); + switch($oper){ + case "in": + return in_array($evaled[0], $evaled[1]); + case "==": + return $evaled[0] == $evaled[1]; + case "list": + return $evaled; + default: + return false; + } + } + }else{ + if($expr instanceof VTEventConditionSymbol){ + return $this->get($this->data, $expr->name); + }else{ + return $expr; + } + } + } + + private function get($obj, $field){ + if(is_array($obj)){ + return $obj[$field]; + }else{ + $func = "get".ucwords($field); + return $obj->$func(); + } + + } + } +?> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/events/VTEventConditionParserLexer.php b/oss/vtiger/trunk/include/events/VTEventConditionParserLexer.php new file mode 100644 index 00000000..d6c26155 --- /dev/null +++ b/oss/vtiger/trunk/include/events/VTEventConditionParserLexer.php @@ -0,0 +1,729 @@ +"; + $transitionS = array( + "\x2\xa\x2\xff\x1\xa\x12\xff\x1\xa\x6\xff\x1\x7\x4\xff\x1\x3\x1\xff". + "\x1\x9\x1\xff\xa\x6\x3\xff\x1\x1\x3\xff\x8\x8\x1\x5\x11\x8\x1\x2". + "\x1\xff\x1\x4\x2\xff\x9\x8\x1\x5\x11\x8", + "", + "", + "", + "", + "\x1\xb\x1f\xff\x1\xb", + "\xa\x6\x3e\xff\x1\xd", + "", + "", + "", + "", + "\xa\x8\x7\xff\x1a\x8\x4\xff\x1\x8\x1\xff\x1a\x8", + "", + "", + "" + ); + $arr = array(); + $arr['eot'] = DFA::unpackEncodedString($eotS); + $arr['eof'] = DFA::unpackEncodedString($eofS); + $arr['min'] = DFA::unpackEncodedString($minS); + $arr['max'] = DFA::unpackEncodedString($maxS); + $arr['accept'] = DFA::unpackEncodedString($acceptS); + $arr['special'] = DFA::unpackEncodedString($specialS); + + + $numStates = sizeof($transitionS); + $arr['transition'] = array(); + for ($i=0; $i<$numStates; $i++) { + $arr['transition'][$i] = DFA::unpackEncodedString($transitionS[$i]); + } + return $arr; +} +$VTEventConditionParserLexer_DFA9 = VTEventConditionParserLexer_DFA9_static(); + +class VTEventConditionParserLexer_DFA9 extends DFA { + + public function __construct($recognizer) { + global $VTEventConditionParserLexer_DFA9; + $DFA = $VTEventConditionParserLexer_DFA9; + $this->recognizer = $recognizer; + $this->decisionNumber = 9; + $this->eot = $DFA['eot']; + $this->eof = $DFA['eof']; + $this->min = $DFA['min']; + $this->max = $DFA['max']; + $this->accept = $DFA['accept']; + $this->special = $DFA['special']; + $this->transition = $DFA['transition']; + } + public function getDescription() { + return "1:1: Tokens : ( T__13 | T__14 | T__15 | T__16 | IN | INTEGER | STRING | SYMBOL | DOT | ELEMENT_ID | WHITESPACE );"; + } +} + + +class VTEventConditionParserLexer extends AntlrLexer { + static $INTEGER=8; + static $T__16=16; + static $IN=5; + static $T__15=15; + static $SYMBOL=4; + static $T__14=14; + static $LETTER=9; + static $T__13=13; + static $WHITESPACE=12; + static $DIGIT=7; + static $DOT=10; + static $EOF=-1; + static $ELEMENT_ID=11; + static $STRING=6; + + public function reportError($e) { + print_r($e); + throw new Exception("The condition you provided is invalid"); + } + + + // delegates + // delegators + + function __construct($input, $state=null){ + parent::__construct($input,$state); + + + $this->dfa9 = new VTEventConditionParserLexer_DFA9($this); + } + function getGrammarFileName() { return "VTEventConditionParser.g"; } + + // $ANTLR start "T__13" + function mT__13(){ + try { + $_type = VTEventConditionParserLexer::$T__13; + $_channel = VTEventConditionParserLexer::$DEFAULT_TOKEN_CHANNEL; + { + $this->matchString("=="); + + + } + + $this->state->type = $_type; + $this->state->channel = $_channel; + } + catch(Exception $e){ + throw $e; + } + } + // $ANTLR end "T__13" + + // $ANTLR start "T__14" + function mT__14(){ + try { + $_type = VTEventConditionParserLexer::$T__14; + $_channel = VTEventConditionParserLexer::$DEFAULT_TOKEN_CHANNEL; + { + $this->matchChar(91); + + } + + $this->state->type = $_type; + $this->state->channel = $_channel; + } + catch(Exception $e){ + throw $e; + } + } + // $ANTLR end "T__14" + + // $ANTLR start "T__15" + function mT__15(){ + try { + $_type = VTEventConditionParserLexer::$T__15; + $_channel = VTEventConditionParserLexer::$DEFAULT_TOKEN_CHANNEL; + { + $this->matchChar(44); + + } + + $this->state->type = $_type; + $this->state->channel = $_channel; + } + catch(Exception $e){ + throw $e; + } + } + // $ANTLR end "T__15" + + // $ANTLR start "T__16" + function mT__16(){ + try { + $_type = VTEventConditionParserLexer::$T__16; + $_channel = VTEventConditionParserLexer::$DEFAULT_TOKEN_CHANNEL; + { + $this->matchChar(93); + + } + + $this->state->type = $_type; + $this->state->channel = $_channel; + } + catch(Exception $e){ + throw $e; + } + } + // $ANTLR end "T__16" + + // $ANTLR start "IN" + function mIN(){ + try { + $_type = VTEventConditionParserLexer::$IN; + $_channel = VTEventConditionParserLexer::$DEFAULT_TOKEN_CHANNEL; + { + if ( $this->input->LA(1)==73||$this->input->LA(1)==105 ) { + $this->input->consume(); + + } + else { + $mse = new MismatchedSetException(null,$this->input); + $this->recover($mse); + throw $mse;} + + if ( $this->input->LA(1)==78||$this->input->LA(1)==110 ) { + $this->input->consume(); + + } + else { + $mse = new MismatchedSetException(null,$this->input); + $this->recover($mse); + throw $mse;} + + + } + + $this->state->type = $_type; + $this->state->channel = $_channel; + } + catch(Exception $e){ + throw $e; + } + } + // $ANTLR end "IN" + + // $ANTLR start "INTEGER" + function mINTEGER(){ + try { + $_type = VTEventConditionParserLexer::$INTEGER; + $_channel = VTEventConditionParserLexer::$DEFAULT_TOKEN_CHANNEL; + { + $cnt1=0; + //loop1: + do { + $alt1=2; + $LA1_0 = $this->input->LA(1); + + if ( (($LA1_0>=$this->getToken('48') && $LA1_0<=$this->getToken('57'))) ) { + $alt1=1; + } + + + switch ($alt1) { + case 1 : + { + $this->mDIGIT(); + + } + break; + + default : + if ( $cnt1 >= 1 ) break 2;//loop1; + $eee = + new EarlyExitException(1, $this->input); + throw $eee; + } + $cnt1++; + } while (true); + + + } + + $this->state->type = $_type; + $this->state->channel = $_channel; + } + catch(Exception $e){ + throw $e; + } + } + // $ANTLR end "INTEGER" + + // $ANTLR start "STRING" + function mSTRING(){ + try { + $_type = VTEventConditionParserLexer::$STRING; + $_channel = VTEventConditionParserLexer::$DEFAULT_TOKEN_CHANNEL; + { + $this->matchChar(39); + $cnt2=0; + //loop2: + do { + $alt2=3; + $LA2_0 = $this->input->LA(1); + + if ( ($LA2_0==$this->getToken('39')) ) { + $LA2_1 = $this->input->LA(2); + + if ( ($LA2_1==$this->getToken('39')) ) { + $alt2=2; + } + + + } + else if ( (($LA2_0>=$this->getToken('0') && $LA2_0<=$this->getToken('38'))||($LA2_0>=$this->getToken('40') && $LA2_0<=$this->getToken('65534'))) ) { + $alt2=1; + } + + + switch ($alt2) { + case 1 : + { + if ( ($this->input->LA(1)>=$this->getToken('0') && $this->input->LA(1)<=$this->getToken('38'))||($this->input->LA(1)>=$this->getToken('40') && $this->input->LA(1)<=$this->getToken('65534')) ) { + $this->input->consume(); + + } + else { + $mse = new MismatchedSetException(null,$this->input); + $this->recover($mse); + throw $mse;} + + + } + break; + case 2 : + { + $this->matchString("\'\'"); + + + } + break; + + default : + if ( $cnt2 >= 1 ) break 2;//loop2; + $eee = + new EarlyExitException(2, $this->input); + throw $eee; + } + $cnt2++; + } while (true); + + $this->matchChar(39); + + } + + $this->state->type = $_type; + $this->state->channel = $_channel; + } + catch(Exception $e){ + throw $e; + } + } + // $ANTLR end "STRING" + + // $ANTLR start "SYMBOL" + function mSYMBOL(){ + try { + $_type = VTEventConditionParserLexer::$SYMBOL; + $_channel = VTEventConditionParserLexer::$DEFAULT_TOKEN_CHANNEL; + $alt5=2; + $LA5_0 = $this->input->LA(1); + + if ( (($LA5_0>=$this->getToken('65') && $LA5_0<=$this->getToken('90'))||($LA5_0>=$this->getToken('97') && $LA5_0<=$this->getToken('122'))) ) { + $alt5=1; + } + else if ( ($LA5_0==$this->getToken('96')) ) { + $alt5=2; + } + else { + $nvae = new NoViableAltException("", 5, 0, $this->input); + + throw $nvae; + } + switch ($alt5) { + case 1 : + { + $this->mLETTER(); + { + //loop3: + do { + $alt3=2; + $LA3_0 = $this->input->LA(1); + + if ( (($LA3_0>=$this->getToken('48') && $LA3_0<=$this->getToken('57'))||($LA3_0>=$this->getToken('65') && $LA3_0<=$this->getToken('90'))||$LA3_0==$this->getToken('95')||($LA3_0>=$this->getToken('97') && $LA3_0<=$this->getToken('122'))) ) { + $alt3=1; + } + + + switch ($alt3) { + case 1 : + { + if ( ($this->input->LA(1)>=$this->getToken('48') && $this->input->LA(1)<=$this->getToken('57'))||($this->input->LA(1)>=$this->getToken('65') && $this->input->LA(1)<=$this->getToken('90'))||$this->input->LA(1)==95||($this->input->LA(1)>=$this->getToken('97') && $this->input->LA(1)<=$this->getToken('122')) ) { + $this->input->consume(); + + } + else { + $mse = new MismatchedSetException(null,$this->input); + $this->recover($mse); + throw $mse;} + + + } + break; + + default : + break 2;//loop3; + } + } while (true); + + + } + + + } + break; + case 2 : + { + $this->matchChar(96); + $cnt4=0; + //loop4: + do { + $alt4=2; + $LA4_0 = $this->input->LA(1); + + if ( (($LA4_0>=$this->getToken('0') && $LA4_0<=$this->getToken('95'))||($LA4_0>=$this->getToken('97') && $LA4_0<=$this->getToken('65534'))) ) { + $alt4=1; + } + + + switch ($alt4) { + case 1 : + { + if ( ($this->input->LA(1)>=$this->getToken('0') && $this->input->LA(1)<=$this->getToken('95'))||($this->input->LA(1)>=$this->getToken('97') && $this->input->LA(1)<=$this->getToken('65534')) ) { + $this->input->consume(); + + } + else { + $mse = new MismatchedSetException(null,$this->input); + $this->recover($mse); + throw $mse;} + + + } + break; + + default : + if ( $cnt4 >= 1 ) break 2;//loop4; + $eee = + new EarlyExitException(4, $this->input); + throw $eee; + } + $cnt4++; + } while (true); + + $this->matchChar(96); + + } + break; + + } + $this->state->type = $_type; + $this->state->channel = $_channel; + } + catch(Exception $e){ + throw $e; + } + } + // $ANTLR end "SYMBOL" + + // $ANTLR start "DOT" + function mDOT(){ + try { + $_type = VTEventConditionParserLexer::$DOT; + $_channel = VTEventConditionParserLexer::$DEFAULT_TOKEN_CHANNEL; + { + $this->matchChar(46); + + } + + $this->state->type = $_type; + $this->state->channel = $_channel; + } + catch(Exception $e){ + throw $e; + } + } + // $ANTLR end "DOT" + + // $ANTLR start "ELEMENT_ID" + function mELEMENT_ID(){ + try { + $_type = VTEventConditionParserLexer::$ELEMENT_ID; + $_channel = VTEventConditionParserLexer::$DEFAULT_TOKEN_CHANNEL; + { + $cnt6=0; + //loop6: + do { + $alt6=2; + $LA6_0 = $this->input->LA(1); + + if ( (($LA6_0>=$this->getToken('48') && $LA6_0<=$this->getToken('57'))) ) { + $alt6=1; + } + + + switch ($alt6) { + case 1 : + { + $this->mDIGIT(); + + } + break; + + default : + if ( $cnt6 >= 1 ) break 2;//loop6; + $eee = + new EarlyExitException(6, $this->input); + throw $eee; + } + $cnt6++; + } while (true); + + $this->matchChar(120); + $cnt7=0; + //loop7: + do { + $alt7=2; + $LA7_0 = $this->input->LA(1); + + if ( (($LA7_0>=$this->getToken('48') && $LA7_0<=$this->getToken('57'))) ) { + $alt7=1; + } + + + switch ($alt7) { + case 1 : + { + $this->mDIGIT(); + + } + break; + + default : + if ( $cnt7 >= 1 ) break 2;//loop7; + $eee = + new EarlyExitException(7, $this->input); + throw $eee; + } + $cnt7++; + } while (true); + + + } + + $this->state->type = $_type; + $this->state->channel = $_channel; + } + catch(Exception $e){ + throw $e; + } + } + // $ANTLR end "ELEMENT_ID" + + // $ANTLR start "LETTER" + function mLETTER(){ + try { + { + if ( ($this->input->LA(1)>=$this->getToken('65') && $this->input->LA(1)<=$this->getToken('90'))||($this->input->LA(1)>=$this->getToken('97') && $this->input->LA(1)<=$this->getToken('122')) ) { + $this->input->consume(); + + } + else { + $mse = new MismatchedSetException(null,$this->input); + $this->recover($mse); + throw $mse;} + + + } + + } + catch(Exception $e){ + throw $e; + } + } + // $ANTLR end "LETTER" + + // $ANTLR start "DIGIT" + function mDIGIT(){ + try { + { + $this->matchRange(48,57); + + } + + } + catch(Exception $e){ + throw $e; + } + } + // $ANTLR end "DIGIT" + + // $ANTLR start "WHITESPACE" + function mWHITESPACE(){ + try { + $_type = VTEventConditionParserLexer::$WHITESPACE; + $_channel = VTEventConditionParserLexer::$DEFAULT_TOKEN_CHANNEL; + { + $cnt8=0; + //loop8: + do { + $alt8=2; + $LA8_0 = $this->input->LA(1); + + if ( (($LA8_0>=$this->getToken('9') && $LA8_0<=$this->getToken('10'))||$LA8_0==$this->getToken('13')||$LA8_0==$this->getToken('32')) ) { + $alt8=1; + } + + + switch ($alt8) { + case 1 : + { + if ( ($this->input->LA(1)>=$this->getToken('9') && $this->input->LA(1)<=$this->getToken('10'))||$this->input->LA(1)==13||$this->input->LA(1)==32 ) { + $this->input->consume(); + + } + else { + $mse = new MismatchedSetException(null,$this->input); + $this->recover($mse); + throw $mse;} + + + } + break; + + default : + if ( $cnt8 >= 1 ) break 2;//loop8; + $eee = + new EarlyExitException(8, $this->input); + throw $eee; + } + $cnt8++; + } while (true); + + $_channel=self::$HIDDEN; + + } + + $this->state->type = $_type; + $this->state->channel = $_channel; + } + catch(Exception $e){ + throw $e; + } + } + // $ANTLR end "WHITESPACE" + + function mTokens(){ + $alt9=11; + $alt9 = $this->dfa9->predict($this->input); + switch ($alt9) { + case 1 : + { + $this->mT__13(); + + } + break; + case 2 : + { + $this->mT__14(); + + } + break; + case 3 : + { + $this->mT__15(); + + } + break; + case 4 : + { + $this->mT__16(); + + } + break; + case 5 : + { + $this->mIN(); + + } + break; + case 6 : + { + $this->mINTEGER(); + + } + break; + case 7 : + { + $this->mSTRING(); + + } + break; + case 8 : + { + $this->mSYMBOL(); + + } + break; + case 9 : + { + $this->mDOT(); + + } + break; + case 10 : + { + $this->mELEMENT_ID(); + + } + break; + case 11 : + { + $this->mWHITESPACE(); + + } + break; + + } + + } + + + +} +?> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/events/VTEventConditionParserParser.php b/oss/vtiger/trunk/include/events/VTEventConditionParserParser.php new file mode 100644 index 00000000..184090f5 --- /dev/null +++ b/oss/vtiger/trunk/include/events/VTEventConditionParserParser.php @@ -0,0 +1,354 @@ +", "", "", "", "SYMBOL", "IN", "STRING", "DIGIT", "INTEGER", "LETTER", "DOT", "ELEMENT_ID", "WHITESPACE", "'=='", "'['", "','", "']'" + ); + public $INTEGER=8; + public $T__16=16; + public $IN=5; + public $T__15=15; + public $SYMBOL=4; + public $LETTER=9; + public $T__14=14; + public $T__13=13; + public $WHITESPACE=12; + public $DIGIT=7; + public $DOT=10; + public $EOF=-1; + public $ELEMENT_ID=11; + public $STRING=6; + + // delegates + // delegators + + static $FOLLOW_comparision_in_statement57; + static $FOLLOW_inclause_in_statement63; + static $FOLLOW_SYMBOL_in_comparision78; + static $FOLLOW_13_in_comparision80; + static $FOLLOW_value_in_comparision84; + static $FOLLOW_SYMBOL_in_inclause101; + static $FOLLOW_IN_in_inclause103; + static $FOLLOW_listelement_in_inclause107; + static $FOLLOW_14_in_listelement122; + static $FOLLOW_value_in_listelement126; + static $FOLLOW_15_in_listelement137; + static $FOLLOW_value_in_listelement141; + static $FOLLOW_16_in_listelement147; + static $FOLLOW_STRING_in_value162; + + + + + public function __construct($input, $state = null) { + if($state==null){ + $state = new RecognizerSharedState(); + } + parent::__construct($input, $state); + + + + } + + + public function getTokenNames() { return VTEventConditionParserParser::$tokenNames; } + public function getGrammarFileName() { return "VTEventConditionParser.g"; } + + + protected function mismatch($input, $ttype, $follow){ + throw new MismatchedTokenException($ttype, $input); + } + public function recoverFromMismatchedSet($input, $e, $follow){ + throw $e; + } + + + + // $ANTLR start "statement" + ///* VTEventConditionParser.g:33:1: statement returns [result] : (exp= comparision | exp= inclause ) ; */ + public function statement(){ + $result = null; + + $exp = null; + + + try { + { + $alt1=2; + $LA1_0 = $this->input->LA(1); + + if ( ($LA1_0==$this->getToken('SYMBOL')) ) { + $LA1_1 = $this->input->LA(2); + + if ( ($LA1_1==$this->getToken('13')) ) { + $alt1=1; + } + else if ( ($LA1_1==$this->getToken('IN')) ) { + $alt1=2; + } + else { + if ($this->state->backtracking>0) {$this->state->failed=true; return $result;} + $nvae = new NoViableAltException("", 1, 1, $this->input); + + throw $nvae; + } + } + else { + if ($this->state->backtracking>0) {$this->state->failed=true; return $result;} + $nvae = new NoViableAltException("", 1, 0, $this->input); + + throw $nvae; + } + switch ($alt1) { + case 1 : + { + $this->pushFollow(self::$FOLLOW_comparision_in_statement57); + $exp=$this->comparision(); + + $this->state->_fsp--; + if ($this->state->failed) return $result; + + } + break; + case 2 : + { + $this->pushFollow(self::$FOLLOW_inclause_in_statement63); + $exp=$this->inclause(); + + $this->state->_fsp--; + if ($this->state->failed) return $result; + + } + break; + + } + + if ( $this->state->backtracking==0 ) { + $result=$exp; + } + + } + + } + + catch (RecognitionException $e) { + throw $e; + } + catch(Exception $e) { + throw $e; + } + + return $result; + } + // $ANTLR end "statement" + + + // $ANTLR start "comparision" + ///* VTEventConditionParser.g:35:1: comparision returns [result] : lhs= SYMBOL '==' rhs= value ; */ + public function comparision(){ + $result = null; + + $lhs=null; + $rhs = null; + + + try { + { + $lhs=$this->match($this->input,$this->getToken('SYMBOL'),self::$FOLLOW_SYMBOL_in_comparision78); if ($this->state->failed) return $result; + $this->match($this->input,$this->getToken('13'),self::$FOLLOW_13_in_comparision80); if ($this->state->failed) return $result; + $this->pushFollow(self::$FOLLOW_value_in_comparision84); + $rhs=$this->value(); + + $this->state->_fsp--; + if ($this->state->failed) return $result; + if ( $this->state->backtracking==0 ) { + $result=array('==', new VTEventConditionSymbol(($lhs!=null?$lhs->getText():null)), $rhs); echo $value; + } + + } + + } + + catch (RecognitionException $e) { + throw $e; + } + catch(Exception $e) { + throw $e; + } + + return $result; + } + // $ANTLR end "comparision" + + + // $ANTLR start "inclause" + ///* VTEventConditionParser.g:38:1: inclause returns [result] : lhs= SYMBOL IN rhs= listelement ; */ + public function inclause(){ + $result = null; + + $lhs=null; + $rhs = null; + + + try { + { + $lhs=$this->match($this->input,$this->getToken('SYMBOL'),self::$FOLLOW_SYMBOL_in_inclause101); if ($this->state->failed) return $result; + $this->match($this->input,$this->getToken('IN'),self::$FOLLOW_IN_in_inclause103); if ($this->state->failed) return $result; + $this->pushFollow(self::$FOLLOW_listelement_in_inclause107); + $rhs=$this->listelement(); + + $this->state->_fsp--; + if ($this->state->failed) return $result; + if ( $this->state->backtracking==0 ) { + $result=array('in', new VTEventConditionSymbol(($lhs!=null?$lhs->getText():null)), $rhs); + } + + } + + } + + catch (RecognitionException $e) { + throw $e; + } + catch(Exception $e) { + throw $e; + } + + return $result; + } + // $ANTLR end "inclause" + + + // $ANTLR start "listelement" + ///* VTEventConditionParser.g:40:1: listelement returns [result] : '[' val= value ( ',' val= value )* ']' ; */ + public function listelement(){ + $result = null; + + $val = null; + + + try { + { + $this->match($this->input,$this->getToken('14'),self::$FOLLOW_14_in_listelement122); if ($this->state->failed) return $result; + $this->pushFollow(self::$FOLLOW_value_in_listelement126); + $val=$this->value(); + + $this->state->_fsp--; + if ($this->state->failed) return $result; + if ( $this->state->backtracking==0 ) { + $result = array('list', $val); + } + //loop2: + do { + $alt2=2; + $LA2_0 = $this->input->LA(1); + + if ( ($LA2_0==$this->getToken('15')) ) { + $alt2=1; + } + + + switch ($alt2) { + case 1 : + { + $this->match($this->input,$this->getToken('15'),self::$FOLLOW_15_in_listelement137); if ($this->state->failed) return $result; + $this->pushFollow(self::$FOLLOW_value_in_listelement141); + $val=$this->value(); + + $this->state->_fsp--; + if ($this->state->failed) return $result; + if ( $this->state->backtracking==0 ) { + $result[] = $val; + } + + } + break; + + default : + break 2;//loop2; + } + } while (true); + + $this->match($this->input,$this->getToken('16'),self::$FOLLOW_16_in_listelement147); if ($this->state->failed) return $result; + + } + + } + + catch (RecognitionException $e) { + throw $e; + } + catch(Exception $e) { + throw $e; + } + + return $result; + } + // $ANTLR end "listelement" + + + // $ANTLR start "value" + ///* VTEventConditionParser.g:44:1: value returns [result] : val= STRING ; */ + public function value(){ + $result = null; + + $val=null; + + try { + { + $val=$this->match($this->input,$this->getToken('STRING'),self::$FOLLOW_STRING_in_value162); if ($this->state->failed) return $result; + if ( $this->state->backtracking==0 ) { + $result = stripcslashes(substr(($val!=null?$val->getText():null), 1, strlen(($val!=null?$val->getText():null))-2)); + } + + } + + } + + catch (RecognitionException $e) { + throw $e; + } + catch(Exception $e) { + throw $e; + } + + return $result; + } + // $ANTLR end "value" + + // Delegated rules + + + +} + + + + + +VTEventConditionParserParser::$FOLLOW_comparision_in_statement57 = new Set(array(1)); +VTEventConditionParserParser::$FOLLOW_inclause_in_statement63 = new Set(array(1)); +VTEventConditionParserParser::$FOLLOW_SYMBOL_in_comparision78 = new Set(array(13)); +VTEventConditionParserParser::$FOLLOW_13_in_comparision80 = new Set(array(6)); +VTEventConditionParserParser::$FOLLOW_value_in_comparision84 = new Set(array(1)); +VTEventConditionParserParser::$FOLLOW_SYMBOL_in_inclause101 = new Set(array(5)); +VTEventConditionParserParser::$FOLLOW_IN_in_inclause103 = new Set(array(14)); +VTEventConditionParserParser::$FOLLOW_listelement_in_inclause107 = new Set(array(1)); +VTEventConditionParserParser::$FOLLOW_14_in_listelement122 = new Set(array(6)); +VTEventConditionParserParser::$FOLLOW_value_in_listelement126 = new Set(array(15, 16)); +VTEventConditionParserParser::$FOLLOW_15_in_listelement137 = new Set(array(6)); +VTEventConditionParserParser::$FOLLOW_value_in_listelement141 = new Set(array(15, 16)); +VTEventConditionParserParser::$FOLLOW_16_in_listelement147 = new Set(array(1)); +VTEventConditionParserParser::$FOLLOW_STRING_in_value162 = new Set(array(1)); + +?> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/events/VTEventConditionSymbol.php b/oss/vtiger/trunk/include/events/VTEventConditionSymbol.php new file mode 100644 index 00000000..7ffb30f4 --- /dev/null +++ b/oss/vtiger/trunk/include/events/VTEventConditionSymbol.php @@ -0,0 +1,16 @@ +name=$name; + } + } +?> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/events/VTEventHandler.inc b/oss/vtiger/trunk/include/events/VTEventHandler.inc new file mode 100644 index 00000000..874f64b9 --- /dev/null +++ b/oss/vtiger/trunk/include/events/VTEventHandler.inc @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/oss/vtiger/trunk/include/events/VTEventTrigger.inc b/oss/vtiger/trunk/include/events/VTEventTrigger.inc new file mode 100644 index 00000000..e0188997 --- /dev/null +++ b/oss/vtiger/trunk/include/events/VTEventTrigger.inc @@ -0,0 +1,125 @@ +$v) { + if(!self::isCached($k) || $force) { + self::$cache[$forname] = $evtinfos; + } + } + } else { + if(!self::isCached() || $force) { + self::$cache = self::getActiveEventInfos($adb, $name); + self::$cacheLookupType = self::CACHE_LOOKUP_TYPE_ALL; + } + } + } + static function isCached($name = false) { + if($name === false) { + if(self::$cacheLookupType == self::CACHE_LOOKUP_TYPE_ALL) { + // Was init cache done for ALL earlier? + return true; + } + } else { + return isset(self::$cache[$name]); + } + return false; + } + static function clearCache($name = false) { + if($name === false) { + self::$cache = array(); + self::$cacheLookupType = ''; + } else if(self::isCached($name)) { + unset(self::$cache[$name]); + } + } + static function lookupCache($name) { + if(self::isCached($name)) { + return self::$cache[$name]; + } else if(self::$cacheLookupType == self::CACHE_LOOKUP_TYPE_ALL) { + return array(); + } + return false; + } + + static function getActiveEventInfos($adb, $name = false) { + $params = array(); + $query = "SELECT * FROM vtiger_eventhandlers WHERE is_active=true"; + if($name !== false) { + if(is_array($name)) { + $query .= " AND event_name IN (" . generateQuestionMarks($name) . ")"; + } else { + $query .= " AND event_name = ?"; + } + $params[] = $name; + } + + $evtinfosbyname = array(); + + $result= $adb->pquery($query, $params); + $it = new SqlResultIterator($adb, $result); + foreach($it as $row) { + $evtinfosbyname[$row->event_name][] = array( + 'condition' => $row->cond, + 'handler_class' => $row->handler_class, + 'handler_path' => $row->handler_path + ); + } + + if($name) return $evtinfosbyname[$name]; + else return $evtinfosbyname; + } + /** END **/ + + function __construct($adb, $name){ + $this->name=$name; + $this->adb = $adb; + } + + function trigger($data){ + $adb = $this->adb; + + $eventInfos = self::lookupCache($this->name); + if($eventInfos === false) { + $eventInfos = self::getActiveEventInfos($this->adb, $this->name); + } + + if($eventInfos) { + foreach($eventInfos as $eventInfo){ + $condition = new VTEventCondition($eventInfo['condition']); + if($condition->test($data)){ + require_once($eventInfo['handler_path']); + $handler_class = $eventInfo['handler_class']; + $handler = new $handler_class(); + + $handler->handleEvent($this->name, $data); + } + } + } + } + } +?> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/events/VTEventsManager.inc b/oss/vtiger/trunk/include/events/VTEventsManager.inc new file mode 100644 index 00000000..f5ff67a4 --- /dev/null +++ b/oss/vtiger/trunk/include/events/VTEventsManager.inc @@ -0,0 +1,189 @@ +adb = $adb; + } + + /** + * Register an event handler + * + * @param $forEvent The name of the event to handle + * @param $path The path to the php file containing the handler + * @param $className The name of the VTEventHandler class. + * @param $condition A condition which must evaluate true for the event to be accepted. + */ + function registerHandler($forEvent, $path, $className, $condition=''){ + $adb = $this->adb; + $result = $adb->pquery("SELECT * FROM vtiger_eventhandlers WHERE event_name=? AND handler_path=? AND handler_class=?", + array($forEvent, $path, $className)); + if($adb->num_rows($result)===0){ + $handlerId = $adb->getUniqueId('vtiger_eventhandlers'); + $adb->pquery("insert into vtiger_eventhandlers + (eventhandler_id, event_name, handler_path, handler_class, cond, is_active) + values (?,?,?,?,?, true)", array($handlerId, $forEvent, $path, $className, $condition)); + + $this->clearTriggerCache($forEvent); + } + } + + /** + * Initialize Event Trigger Cache for the required event types. + * + * @param Object $for Optional String or Array of event_names for initializing. + * @param Boolean $force Optional Force the initialization of cache? + */ + function initTriggerCache($for = false, $force = false) { + VTEventTrigger::initCache($for, $force); + } + + /** + * Clear the Event Trigger Cache + * + * @param Object $forEvent + */ + function clearTriggerCache($forEvent = false) { + VTEventTrigger::clearCache($forEvent); + } + + /** + * Set an event handler as inactive + * @param The handler class to set as inactive + * + */ + function setHandlerInActive($handlerClass){ + $adb = $this->adb; + $adb->pquery("update vtiger_eventhandlers set is_active=false where handler_class=?", array($handlerClass)); + + $this->clearTriggerCache(); + } + + /** + * Set an event handler as active + * + * @param The handler class to set as active + */ + function setHandlerActive($handlerClass){ + $adb = $this->adb; + $adb->pquery("update vtiger_eventhandlers set is_active=true where handler_class=?", array($handlerClass)); + + $this->clearTriggerCache(); + } + + + /** + * Unregister a registered handler + * + * @param $className The name of teh VTEventHandler class to unregister + */ + function unregisterHandler($className){ + $adb = $this->adb; + $adb->pquery("delete from vtiger_eventhandlers where handler_class=?", + array($className)); + $adb->pquery("delete from vtiger_eventhandler_module where handler_class=?", + array($className)); + + $this->clearTriggerCache(); + } + + /** + * Get an event triger instance + * + * @param $triggerName The name of the event. + * @return The trigger object for the event. + */ + function getTrigger($triggerName){ + $adb=$this->adb; + return new VTEventTrigger($adb, $triggerName); + } + + /** + * Trigger an event + * + * @param $triggerName The name of the event. + * @return The trigger object for the event. + */ + function triggerEvent($triggerName, $data){ + $this->getTrigger($triggerName)->trigger($data); + } + + /** + * Set the module the handler belongs to + * + * @param moduleName - The name of the module + * @param handlerClass - The name of the handler class + */ + function setModuleForHandler($moduleName, $handlerClass){ + $adb = $this->adb; + $result = $adb->pquery("SELECT * FROM vtiger_eventhandler_module WHERE handler_class=?", + array($handlerClass)); + if($adb->num_rows($result)===0){ + $handlerModuleId = $adb->getUniqueId('vtiger_eventhandler_module'); + $adb->pquery("insert into vtiger_eventhandler_module + (eventhandler_module_id, module_name, handler_class) + values (?,?,?)", array($handlerModuleId, $moduleName, $handlerClass)); + } + } + + /** + * List handler classes for a module + * + * @param moduleName - The name of the module + */ + function listHandlersForModule($moduleName){ + $adb = $this->adb; + $result = $adb->pquery('SELECT handler_class FROM vtiger_eventhandler_module WHERE module_name=?', array($moduleName)); + $it = new SqlResultIterator($adb, $result); + $arr = array(); + foreach($it as $row){ + $arr[] = $row->handler_class; + } + return $arr; + } + + /** + * List active events. + * + * @return A list of registered events. + */ + function listActiveEventHandlers(){ + $adb = $this->adb; + $result = $adb->pquery("select * from vtiger_eventhandlers where is_active=true"); + return $this->listEventHandlers($result); + } + + function listAllEventHandlers(){ + $adb = $this->adb; + $result = $adb->pquery("select * from vtiger_eventhandlers"); + return $this->listEventHandlers($result); + + } + + private function listEventHandlers($result){ + $adb = $this->adb; + $it = new SQLResultIterator($adb, $result); + $out = array(); + foreach($it as $row){ + $el = array(); + $el['eventName'] = $row->event_name; + $el['handlerPath'] = $row->handler_path; + $el['handlerClass'] = $tow->handler_class; + $el['condition'] = $row->cond; + $el['isActive'] = $row->is_active; + $out[] = $el; + } + return $out; + } + } +?> diff --git a/oss/vtiger/trunk/include/events/VTWSEntityType.inc b/oss/vtiger/trunk/include/events/VTWSEntityType.inc new file mode 100644 index 00000000..2805167d --- /dev/null +++ b/oss/vtiger/trunk/include/events/VTWSEntityType.inc @@ -0,0 +1,203 @@ +entityTypeName = $entityTypeName; + $this->description = $describeResult; + } + + function usingGlobalCurrentUser($entityTypeName){ + global $current_user; + return new VTWSEntityType($entityTypeName, $current_user); + + + } + + function forUser($entityTypeName, $user){ + return new VTWSEntityType($entityTypeName, $user); + } + function getTabId(){ + global $adb; + if(!isset($this->tabId)){ + $result = $adb->pquery("select tabid from vtiger_tab where name=?", + array($this->entityTypeName)); + $this->tabId = $adb->query_result($result,0,"tabid"); + } + return $this->tabId; + } + + function getModuleName(){ + return $this->moduleName; + } + + function getFieldNames(){ + if(!isset($this->fieldNames)){ + $fields = $this->description['fields']; + $arr = array(); + foreach($fields as $field){ + $arr[]=$field["name"]; + } + $this->fieldNames = $arr; + } + return $this->fieldNames; + } + + + + function getFieldLabel($fieldName){ + if(!isset($this->fieldLabels)){ + $this->getFieldLabels(); + } + return $this->fieldLabels[$fieldName]; + } + + function getFieldLabels(){ + if(!isset($this->fieldLabels)){ + $fields = $this->description['fields']; + foreach($fields as $field){ + $this->fieldLabels[$field['name']] = $field['label']; + } + } + return $this->fieldLabels; + } + + function getFieldType($fieldName){ + if(!isset($this->fieldTypes[$fieldName])){ + $fields = $this->description['fields']; + foreach($fields as $field){ + if($field['name']==$fieldName){ + $type = $field['type']; + $et = new VTWSFieldType(); + switch($type['name']){ + case 'reference': + $et->type = 'Related'; + $et->relatedTo = $type['refersTo']; + break; + case 'integer': + $et->type = 'Number'; + $et->format = 'Integer'; + break; + case 'url': + $et->type = 'Url'; + break; + case 'string': + $et->type = 'String'; + break; + case 'picklist': + $et->type = 'Select'; + $et->values = $type['picklistValues']; + break; + case 'datetime': + $et->type = 'DateTime'; + break; + case 'email': + $et->type = 'Email'; + break; + case 'boolean': + $et->type = 'Boolean'; + break; + case 'phone': + $et->type = 'Phone'; + break; + case 'text': + $et->type = 'String'; + break; + case 'a'://Autogenerated type is getting messed up for Accounts + $et->type = 'Id'; + break; + case 'date': + $et->type = 'Date'; + break; + case 'time': + $et->type = 'Time'; + break; + case 'double': + $et->type = 'Number'; + $et->format = 'Decimal'; + break; + case 'autogenerated': + $et->type = 'Id'; + break; + case 'owner': + $et->type = 'Owner'; + break; + case 'multipicklist': + $et->type = 'Select'; + $et->values = array(); + break; + case 'skype': + $et->type = 'Skype'; + break; + case 'password': + $et->type = 'Password'; + break; + case 'decimal': + $et->type = 'Number'; + $et->format = 'Decimal'; + break; + default: + print_r($type); + throw new Exception($type["name"]." is not supported yet."); + } + $this->fieldTypes[$fieldName] = $et; + break; + } + } + + } + return $this->fieldTypes[$fieldName]; + } + + function getFieldTypes(){ + $adb = $this->adb; + $fieldNames = $this->getFieldNames(); + $fieldTypes = array(); + foreach($fieldNames as $fieldName){ + $fieldTypes[$fieldName]=$this->getFieldType($fieldName); + } + return $fieldTypes; + } + +} + + + +class VTWSFieldType{ + function toArray(){ + $ro = new ReflectionObject($this); + $props = $ro->getProperties(); + $arr = array(); + foreach($props as $prop){ + $arr[$prop->getName()]=$prop->getValue($this); + } + return $arr; + } +} +?> diff --git a/oss/vtiger/trunk/include/events/include.inc b/oss/vtiger/trunk/include/events/include.inc new file mode 100644 index 00000000..61501f33 --- /dev/null +++ b/oss/vtiger/trunk/include/events/include.inc @@ -0,0 +1,21 @@ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/anchor.gif b/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/anchor.gif new file mode 100644 index 0000000000000000000000000000000000000000..5aa797b2240a432d9f3f1d166ed5542eaf684937 GIT binary patch literal 184 zcmZ?wbhEHb6kygJ|Uu&?oD;%Ae!z@09(NL_hv#6Slx0y!YR{?r|LJZgAju=f-$sQVWNL{+Tsz18#+~Ke%+zTWns()WcPwy8dQcr!JH# U&i)o# + + + + + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/disablehandles.htc b/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/disablehandles.htc new file mode 100644 index 00000000..8dfb661d --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/disablehandles.htc @@ -0,0 +1,15 @@ + + + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/hiddenfield.gif b/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/hiddenfield.gif new file mode 100644 index 0000000000000000000000000000000000000000..12bc251109f5a54b6dd2be2327bd4bf15b9daf71 GIT binary patch literal 111 zcmZ?wbhEHb6k!lyn8?8J|NsAnh6W(Xz`&sRlZ91;fr&u}$Og)aFfcGVOzB^F`mOY$ zIVKmi8+jM}<}Z-;=<*1ud)C-AXS>u}n{4&(kLKF7Wyo#XSmK!A<8b(DmCB5Oww*Q; O&pvzHbvB8c!5RRVzAO6x literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/hiddenfield.htc b/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/hiddenfield.htc new file mode 100644 index 00000000..455484ff --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/hiddenfield.htc @@ -0,0 +1,30 @@ + + + + + + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/moz-bindings.xml b/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/moz-bindings.xml new file mode 100644 index 00000000..111dd11a --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/moz-bindings.xml @@ -0,0 +1,59 @@ + + + + + + this.CheckShowBorders() ; + + + + var oClassRegex = /\s*FCK__ShowTableBorders\s*/ ; + + if ( this.border == 0 ) + { + if ( !oClassRegex.test( this.className ) ) + this.className += ' FCK__ShowTableBorders' ; + } + else + { + if ( oClassRegex.test( this.className ) ) + this.className = this.className.replace( oClassRegex, '' ) ; + } + + + + + + this.CheckShowBorders() ; + + + + + + + 0 && ( this.getAttribute('href') == null || this.getAttribute('href').length == 0 ) ) ; + this.ShowIcon() ; + ]]> + + + + if ( this.IsAnchor ) + { + this.style.height = '1px' ; + this.style.paddingLeft = '16px' ; + this.style.backgroundImage = 'url(behaviors/anchor.gif)' ; + this.style.backgroundRepeat = 'no-repeat' ; + this.style.cursor = 'pointer' ; + } + + + + + + if ( this.IsAnchor ) + alert( this.IsAnchor ) ; + + + + \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/showtableborders.htc b/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/showtableborders.htc new file mode 100644 index 00000000..7fef3f31 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/css/behaviors/showtableborders.htc @@ -0,0 +1,36 @@ + + + + + + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/css/fck_editorarea.css b/oss/vtiger/trunk/include/fckeditor/editor/css/fck_editorarea.css new file mode 100644 index 00000000..305b786f --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/css/fck_editorarea.css @@ -0,0 +1,67 @@ +/* + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: fck_editorarea.css + * This is the default CSS file used by the editor area. It defines the + * initial font of the editor and background color. + * + * A user can configure the editor to use another CSS file. Just change + * the value of the FCKConfig.EditorAreaCSS key in the configuration + * file. + * + * File Authors: + * Frederico Caldeira Knabben (fredck@fckeditor.net) + */ + +body +{ + font-family: Arial, Verdana, Sans-Serif; + font-size: 12px; + padding: 5px 5px 5px 5px; + margin: 0px; + border-style: none; + background-color: #ffffff; +} + +/* + Just uncomment the following block if you want to avoid spaces between + paragraphs. Remember to apply the same style in your output front end page. +*/ +/* +P, UL, LI +{ + margin-top: 0px; + margin-bottom: 0px; +} +*/ + +.Bold +{ + font-weight: bold; +} + +.Title +{ + font-weight: bold; + font-size: 18px; + color: #cc3300; +} + +.Code +{ + border: #8b4513 1px solid; + padding-right: 5px; + padding-left: 5px; + color: #000066; + font-family: 'Courier New' , Monospace; + background-color: #ff9933; +} \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/css/fck_internal.css b/oss/vtiger/trunk/include/fckeditor/editor/css/fck_internal.css new file mode 100644 index 00000000..6ad7abc7 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/css/fck_internal.css @@ -0,0 +1,80 @@ +/* + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: fck_internal.css + * This CSS Style Sheet defines rules used by the editor for its internal use. + * + * File Authors: + * Frederico Caldeira Knabben (fredck@fckeditor.net) + */ + +TABLE.FCK__ShowTableBorders, TABLE.FCK__ShowTableBorders TD, TABLE.FCK__ShowTableBorders TH +{ + border: #d3d3d3 1px solid; +} + +FORM +{ + border: 1px dotted #FF0000; + padding: 2px; +} + +.FCK__Flash +{ + border: darkgray 1px solid; + background-position: center center; + background-image: url(images/fck_flashlogo.gif); + background-repeat: no-repeat; + width: 80px; + height: 80px; +} + +.FCK__Anchor +{ + background-position: center center; + background-image: url(images/fck_anchor.gif); + background-repeat: no-repeat; + width: 16px; + height: 15px; +} + +.FCK__PageBreak +{ + background-position: center center; + background-image: url(images/fck_pagebreak.gif); + background-repeat: no-repeat; + clear: both; + display: block; + float: none; + width: 100%; + border-top: #999999 1px dotted; + border-bottom: #999999 1px dotted; + border-right: 0px; + border-left: 0px; + height: 5px; +} + +input[type="hidden"] +{ + display: inline; + width:20px; + height:20px; + border:1px dotted #FF0000 ; + background-image: url(behaviors/hiddenfield.gif); + background-repeat: no-repeat; +} + +input[type="hidden"]:after +{ + padding-left: 20px; + content: "" ; +} diff --git a/oss/vtiger/trunk/include/fckeditor/editor/css/fck_showtableborders_gecko.css b/oss/vtiger/trunk/include/fckeditor/editor/css/fck_showtableborders_gecko.css new file mode 100644 index 00000000..f92467a4 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/css/fck_showtableborders_gecko.css @@ -0,0 +1,31 @@ +/* + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: fck_showtableborders_gecko.css + * This CSS Style Sheet defines the rules to show table borders on Gecko. + * + * File Authors: + * Frederico Caldeira Knabben (fredck@fckeditor.net) + */ +TABLE[border="0"], +TABLE[border="0"] > TR > TD, TABLE[border="0"] > TR > TH, +TABLE[border="0"] > TBODY > TR > TD, TABLE[border="0"] > TBODY > TR > TH, +TABLE[border="0"] > THEAD > TR > TD, TABLE[border="0"] > THEAD > TR > TH, +TABLE[border="0"] > TFOOT > TR > TD, TABLE[border="0"] > TFOOT > TR > TH, +TABLE:not([border]), +TABLE:not([border]) > TR > TD, TABLE:not([border]) > TR > TH, +TABLE:not([border]) > TBODY > TR > TD, TABLE:not([border]) > TBODY > TR > TH, +TABLE:not([border]) > THEAD > TR > TD, TABLE:not([border]) > THEAD > TR > TH, +TABLE:not([border]) > TFOOT > TR > TD, TABLE:not([border]) > TFOOT > TR > TH +{ + border: #d3d3d3 1px dotted ; +} diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/fck_dialog_common.css b/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/fck_dialog_common.css new file mode 100644 index 00000000..fab1a747 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/fck_dialog_common.css @@ -0,0 +1,79 @@ +/* + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: fck_dialog_common.css + * This is the CSS file used for interface details in some dialog + * windows. + * + * File Authors: + * Frederico Caldeira Knabben (fredck@fckeditor.net) + */ + +.ImagePreviewArea +{ + border: #000000 1px solid; + overflow: auto; + width: 100%; + height: 170px; + background-color: #ffffff; +} + +.FlashPreviewArea +{ + border: #000000 1px solid; + padding: 5px; + overflow: auto; + width: 100%; + height: 170px; + background-color: #ffffff; +} + +.BtnReset +{ + float: left; + background-position: center center; + background-image: url(images/reset.gif); + width: 16px; + height: 16px; + background-repeat: no-repeat; + border: 1px none; + font-size: 1px ; +} + +.BtnLocked, .BtnUnlocked +{ + float: left; + background-position: center center; + background-image: url(images/locked.gif); + width: 16px; + height: 16px; + background-repeat: no-repeat; + border: 1px none; + font-size: 1px ; +} + +.BtnUnlocked +{ + background-image: url(images/unlocked.gif); +} + +.BtnOver +{ + border: 1px outset; + cursor: pointer; + cursor: hand; +} + +.FCK__FieldNumeric +{ + behavior: url(common/fcknumericfield.htc) ; +} \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/fck_dialog_common.js b/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/fck_dialog_common.js new file mode 100644 index 00000000..bc3a1386 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/fck_dialog_common.js @@ -0,0 +1,125 @@ +/* + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: fck_dialog_common.js + * Useful functions used by almost all dialog window pages. + * + * File Authors: + * Frederico Caldeira Knabben (fredck@fckeditor.net) + */ + +// Gets a element by its Id. Used for shorter coding. +function GetE( elementId ) +{ + return document.getElementById( elementId ) ; +} + +function ShowE( element, isVisible ) +{ + if ( typeof( element ) == 'string' ) + element = GetE( element ) ; + element.style.display = isVisible ? '' : 'none' ; +} + +function SetAttribute( element, attName, attValue ) +{ + if ( attValue == null || attValue.length == 0 ) + element.removeAttribute( attName, 0 ) ; // 0 : Case Insensitive + else + element.setAttribute( attName, attValue, 0 ) ; // 0 : Case Insensitive +} + +function GetAttribute( element, attName, valueIfNull ) +{ + var oAtt = element.attributes[attName] ; + + if ( oAtt == null || !oAtt.specified ) + return valueIfNull ? valueIfNull : '' ; + + var oValue ; + + if ( !( oValue = element.getAttribute( attName, 2 ) ) ) + oValue = oAtt.nodeValue ; + + return ( oValue == null ? valueIfNull : oValue ) ; +} + +// Functions used by text fiels to accept numbers only. +function IsDigit( e ) +{ + e = e || event ; + var iCode = ( e.keyCode || e.charCode ) ; + + event.returnValue = + ( + ( iCode >= 48 && iCode <= 57 ) // Numbers + || (iCode >= 37 && iCode <= 40) // Arrows + || iCode == 8 // Backspace + || iCode == 46 // Delete + ) ; + + return event.returnValue ; +} + +String.prototype.trim = function() +{ + return this.replace( /(^\s*)|(\s*$)/g, '' ) ; +} + +String.prototype.startsWith = function( value ) +{ + return ( this.substr( 0, value.length ) == value ) ; +} + +String.prototype.remove = function( start, length ) +{ + var s = '' ; + + if ( start > 0 ) + s = this.substring( 0, start ) ; + + if ( start + length < this.length ) + s += this.substring( start + length , this.length ) ; + + return s ; +} + +function OpenFileBrowser( url, width, height ) +{ + // oEditor must be defined. + + var iLeft = ( oEditor.FCKConfig.ScreenWidth - width ) / 2 ; + var iTop = ( oEditor.FCKConfig.ScreenHeight - height ) / 2 ; + + var sOptions = "toolbar=no,status=no,resizable=yes,dependent=yes" ; + sOptions += ",width=" + width ; + sOptions += ",height=" + height ; + sOptions += ",left=" + iLeft ; + sOptions += ",top=" + iTop ; + + // The "PreserveSessionOnFileBrowser" because the above code could be + // blocked by popup blockers. + if ( oEditor.FCKConfig.PreserveSessionOnFileBrowser && oEditor.FCKBrowserInfo.IsIE ) + { + // The following change has been made otherwise IE will open the file + // browser on a different server session (on some cases): + // http://support.microsoft.com/default.aspx?scid=kb;en-us;831678 + // by Simone Chiaretta. + var oWindow = oEditor.window.open( url, 'FCKBrowseWindow', sOptions ) ; + if ( oWindow ) + oWindow.opener = window ; + else + alert( oEditor.FCKLang.BrowseServerBlocked ) ; + } + else + window.open( url, 'FCKBrowseWindow', sOptions ) ; +} \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/fcknumericfield.htc b/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/fcknumericfield.htc new file mode 100644 index 00000000..74f26d0d --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/fcknumericfield.htc @@ -0,0 +1,24 @@ + + + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/images/locked.gif b/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/images/locked.gif new file mode 100644 index 0000000000000000000000000000000000000000..ea0787002229d32d374193a96f5d57d4cb411988 GIT binary patch literal 74 zcmZ?wbhEHbqhLlW7NWPalw|wDT>Y41KDa5B1(AN8J-K6Jhxuv(;()*EkSH0kHq~$&M_(s4Auan CRv``m literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/images/unlocked.gif b/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/images/unlocked.gif new file mode 100644 index 0000000000000000000000000000000000000000..801e423c741b39f3d7da2e1bd111e8ed889d5602 GIT binary patch literal 75 zcmZ?wbhEHbOD&BLeKO=)R0Q995zyJUM literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/moz-bindings.xml b/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/moz-bindings.xml new file mode 100644 index 00000000..b056123b --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/common/moz-bindings.xml @@ -0,0 +1,28 @@ + + + + + + this.keypress = CheckIsDigit ; + + + + var iCode = keyCode ; + + var bAccepted = + ( + ( iCode >= 48 && iCode <= 57 ) // Numbers + || (iCode >= 37 && iCode <= 40) // Arrows + || iCode == 8 // Backspace + || iCode == 46 // Delete + ) ; + + return bAccepted ; + + + + + + + + \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_about.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_about.html new file mode 100644 index 00000000..3eae0035 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_about.html @@ -0,0 +1,144 @@ + + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + +
+ version +
+ 2.2
+
+  
+ Support Open Source software.
+ + What about a donation today?
+


+ For further information go to + http://www.fckeditor.net/. +
+ Copyright © 2003-2005 Frederico Caldeira + Knabben +
+ +
+
+ + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_about/lgpl.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_about/lgpl.html new file mode 100644 index 00000000..7dfce1d5 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_about/lgpl.html @@ -0,0 +1,434 @@ + + + + GNU Lesser General Public License + + + + +

GNU Lesser General Public License

+ +

Version 2.1, February 1999

+
+

Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite + 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute + verbatim copies of this license document, but changing it is not allowed.

+

[This is the first released version of the Lesser GPL. It also counts as the + successor of the GNU Library Public License, version 2, hence the version + number 2.1.]

+
+

Preamble

+

The licenses for most software are designed to take away your freedom to share + and change it. By contrast, the GNU General Public Licenses are intended to + guarantee your freedom to share and change free software--to make sure the + software is free for all its users. +

+

This license, the Lesser General Public License, applies to some specially + designated software packages--typically libraries--of the Free Software + Foundation and other authors who decide to use it. You can use it too, but we + suggest you first think carefully about whether this license or the ordinary + General Public License is the better strategy to use in any particular case, + based on the explanations below. +

+

When we speak of free software, we are referring to freedom of use, not price. + Our General Public Licenses are designed to make sure that you have the freedom + to distribute copies of free software (and charge for this service if you + wish); that you receive source code or can get it if you want it; that you can + change the software and use pieces of it in new free programs; and that you are + informed that you can do these things.

+

To protect your rights, we need to make restrictions that forbid distributors to + deny you these rights or to ask you to surrender these rights. These + restrictions translate to certain responsibilities for you if you distribute + copies of the library or if you modify it. +

+

For example, if you distribute copies of the library, whether gratis or for a + fee, you must give the recipients all the rights that we gave you. You must + make sure that they, too, receive or can get the source code. If you link other + code with the library, you must provide complete object files to the + recipients, so that they can relink them with the library after making changes + to the library and recompiling it. And you must show them these terms so they + know their rights. +

+

We protect your rights with a two-step method: (1) we copyright the library, and + (2) we offer you this license, which gives you legal permission to copy, + distribute and/or modify the library. +

+

To protect each distributor, we want to make it very clear that there is no + warranty for the free library. Also, if the library is modified by someone else + and passed on, the recipients should know that what they have is not the + original version, so that the original author's reputation will not be affected + by problems that might be introduced by others. +

+

Finally, software patents pose a constant threat to the existence of any free + program. We wish to make sure that a company cannot effectively restrict the + users of a free program by obtaining a restrictive license from a patent + holder. Therefore, we insist that any patent license obtained for a version of + the library must be consistent with the full freedom of use specified in this + license. +

+

Most GNU software, including some libraries, is covered by the ordinary GNU + General Public License. This license, the GNU Lesser General Public License, + applies to certain designated libraries, and is quite different from the + ordinary General Public License. We use this license for certain libraries in + order to permit linking those libraries into non-free programs. +

+

When a program is linked with a library, whether statically or using a shared + library, the combination of the two is legally speaking a combined work, a + derivative of the original library. The ordinary General Public License + therefore permits such linking only if the entire combination fits its criteria + of freedom. The Lesser General Public License permits more lax criteria for + linking other code with the library. +

+

We call this license the "Lesser" General Public License because it does Less to + protect the user's freedom than the ordinary General Public License. It also + provides other free software developers Less of an advantage over competing + non-free programs. These disadvantages are the reason we use the ordinary + General Public License for many libraries. However, the Lesser license provides + advantages in certain special circumstances. +

+

For example, on rare occasions, there may be a special need to encourage the + widest possible use of a certain library, so that it becomes a de-facto + standard. To achieve this, non-free programs must be allowed to use the + library. A more frequent case is that a free library does the same job as + widely used non-free libraries. In this case, there is little to gain by + limiting the free library to free software only, so we use the Lesser General + Public License. +

+

In other cases, permission to use a particular library in non-free programs + enables a greater number of people to use a large body of free software. For + example, permission to use the GNU C Library in non-free programs enables many + more people to use the whole GNU operating system, as well as its variant, the + GNU/Linux operating system. +

+

Although the Lesser General Public License is Less protective of the users' + freedom, it does ensure that the user of a program that is linked with the + Library has the freedom and the wherewithal to run that program using a + modified version of the Library. +

+

The precise terms and conditions for copying, distribution and modification + follow. Pay close attention to the difference between a "work based on the + library" and a "work that uses the library". The former contains code derived + from the library, whereas the latter must be combined with the library in order + to run. +

+

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+

0. This License Agreement applies to any software library or + other program which contains a notice placed by the copyright holder or other + authorized party saying it may be distributed under the terms of this Lesser + General Public License (also called "this License"). Each licensee is addressed + as "you".

+

A "library" means a collection of software functions and/or data prepared so as + to be conveniently linked with application programs (which use some of those + functions and data) to form executables. +

+

The "Library", below, refers to any such software library or work which has been + distributed under these terms. A "work based on the Library" means either the + Library or any derivative work under copyright law: that is to say, a work + containing the Library or a portion of it, either verbatim or with + modifications and/or translated straightforwardly into another language. + (Hereinafter, translation is included without limitation in the term + "modification".) +

+

"Source code" for a work means the preferred form of the work for making + modifications to it. For a library, complete source code means all the source + code for all modules it contains, plus any associated interface definition + files, plus the scripts used to control compilation and installation of the + library.

+

Activities other than copying, distribution and modification are not covered by + this License; they are outside its scope. The act of running a program using + the Library is not restricted, and output from such a program is covered only + if its contents constitute a work based on the Library (independent of the use + of the Library in a tool for writing it). Whether that is true depends on what + the Library does and what the program that uses the Library does. +

+

1. You may copy and distribute verbatim copies of the Library's + complete source code as you receive it, in any medium, provided that you + conspicuously and appropriately publish on each copy an appropriate copyright + notice and disclaimer of warranty; keep intact all the notices that refer to + this License and to the absence of any warranty; and distribute a copy of this + License along with the Library. +

+

You may charge a fee for the physical act of transferring a copy, and you may at + your option offer warranty protection in exchange for a fee. +

+

2. You may modify your copy or copies of the Library or any + portion of it, thus forming a work based on the Library, and copy and + distribute such modifications or work under the terms of Section 1 above, + provided that you also meet all of these conditions: +

+
+

a) The modified work must itself be a software library. +

+

b) You must cause the files modified to carry prominent notices stating that you + changed the files and the date of any change.

+

c) You must cause the whole of the work to be licensed at no charge to all third + parties under the terms of this License. +

+

d) If a facility in the modified Library refers to a function or a table of data + to be supplied by an application program that uses the facility, other than as + an argument passed when the facility is invoked, then you must make a good + faith effort to ensure that, in the event an application does not supply such + function or table, the facility still operates, and performs whatever part of + its purpose remains meaningful. +

+

(For example, a function in a library to compute square roots has a purpose that + is entirely well-defined independent of the application. Therefore, Subsection + 2d requires that any application-supplied function or table used by this + function must be optional: if the application does not supply it, the square + root function must still compute square roots.) +

+

These requirements apply to the modified work as a whole. If identifiable + sections of that work are not derived from the Library, and can be reasonably + considered independent and separate works in themselves, then this License, and + its terms, do not apply to those sections when you distribute them as separate + works. But when you distribute the same sections as part of a whole which is a + work based on the Library, the distribution of the whole must be on the terms + of this License, whose permissions for other licensees extend to the entire + whole, and thus to each and every part regardless of who wrote it. +

+

Thus, it is not the intent of this section to claim rights or contest your + rights to work written entirely by you; rather, the intent is to exercise the + right to control the distribution of derivative or collective works based on + the Library. +

+

In addition, mere aggregation of another work not based on the Library with the + Library (or with a work based on the Library) on a volume of a storage or + distribution medium does not bring the other work under the scope of this + License. +

+
+

3. You may opt to apply the terms of the ordinary GNU General + Public License instead of this License to a given copy of the Library. To do + this, you must alter all the notices that refer to this License, so that they + refer to the ordinary GNU General Public License, version 2, instead of to this + License. (If a newer version than version 2 of the ordinary GNU General Public + License has appeared, then you can specify that version instead if you wish.) + Do not make any other change in these notices. +

+

Once this change is made in a given copy, it is irreversible for that copy, so + the ordinary GNU General Public License applies to all subsequent copies and + derivative works made from that copy. +

+

This option is useful when you wish to copy part of the code of the Library into + a program that is not a library. +

+

4. You may copy and distribute the Library (or a portion or + derivative of it, under Section 2) in object code or executable form under the + terms of Sections 1 and 2 above provided that you accompany it with the + complete corresponding machine-readable source code, which must be distributed + under the terms of Sections 1 and 2 above on a medium customarily used for + software interchange. +

+

If distribution of object code is made by offering access to copy from a + designated place, then offering equivalent access to copy the source code from + the same place satisfies the requirement to distribute the source code, even + though third parties are not compelled to copy the source along with the object + code.

+

5. A program that contains no derivative of any portion of the + Library, but is designed to work with the Library by being compiled or linked + with it, is called a "work that uses the Library". Such a work, in isolation, + is not a derivative work of the Library, and therefore falls outside the scope + of this License. +

+

However, linking a "work that uses the Library" with the Library creates an + executable that is a derivative of the Library (because it contains portions of + the Library), rather than a "work that uses the library". The executable is + therefore covered by this License. Section 6 states terms for distribution of + such executables. +

+

When a "work that uses the Library" uses material from a header file that is + part of the Library, the object code for the work may be a derivative work of + the Library even though the source code is not. Whether this is true is + especially significant if the work can be linked without the Library, or if the + work is itself a library. The threshold for this to be true is not precisely + defined by law. +

+

If such an object file uses only numerical parameters, data structure layouts + and accessors, and small macros and small inline functions (ten lines or less + in length), then the use of the object file is unrestricted, regardless of + whether it is legally a derivative work. (Executables containing this object + code plus portions of the Library will still fall under Section 6.) +

+

Otherwise, if the work is a derivative of the Library, you may distribute the + object code for the work under the terms of Section 6. Any executables + containing that work also fall under Section 6, whether or not they are linked + directly with the Library itself. +

+

6. As an exception to the Sections above, you may also combine + or link a "work that uses the Library" with the Library to produce a work + containing portions of the Library, and distribute that work under terms of + your choice, provided that the terms permit modification of the work for the + customer's own use and reverse engineering for debugging such modifications. +

+

You must give prominent notice with each copy of the work that the Library is + used in it and that the Library and its use are covered by this License. You + must supply a copy of this License. If the work during execution displays + copyright notices, you must include the copyright notice for the Library among + them, as well as a reference directing the user to the copy of this License. + Also, you must do one of these things: +

+
+

a) Accompany the work with the complete corresponding machine-readable source + code for the Library including whatever changes were used in the work (which + must be distributed under Sections 1 and 2 above); and, if the work is an + executable linked with the Library, with the complete machine-readable "work + that uses the Library", as object code and/or source code, so that the user can + modify the Library and then relink to produce a modified executable containing + the modified Library. (It is understood that the user who changes the contents + of definitions files in the Library will not necessarily be able to recompile + the application to use the modified definitions.) +

+

b) Use a suitable shared library mechanism for linking with the Library. A + suitable mechanism is one that (1) uses at run time a copy of the library + already present on the user's computer system, rather than copying library + functions into the executable, and (2) will operate properly with a modified + version of the library, if the user installs one, as long as the modified + version is interface-compatible with the version that the work was made with. +

+

c) Accompany the work with a written offer, valid for at least three years, to + give the same user the materials specified in Subsection 6a, above, for a + charge no more than the cost of performing this distribution. +

+

d) If distribution of the work is made by offering access to copy from a + designated place, offer equivalent access to copy the above specified materials + from the same place. +

+

e) Verify that the user has already received a copy of these materials or that + you have already sent this user a copy.

+
+

For an executable, the required form of the "work that uses the Library" must + include any data and utility programs needed for reproducing the executable + from it. However, as a special exception, the materials to be distributed need + not include anything that is normally distributed (in either source or binary + form) with the major components (compiler, kernel, and so on) of the operating + system on which the executable runs, unless that component itself accompanies + the executable. +

+

It may happen that this requirement contradicts the license restrictions of + other proprietary libraries that do not normally accompany the operating + system. Such a contradiction means you cannot use both them and the Library + together in an executable that you distribute. +

+

7. You may place library facilities that are a work based on + the Library side-by-side in a single library together with other library + facilities not covered by this License, and distribute such a combined library, + provided that the separate distribution of the work based on the Library and of + the other library facilities is otherwise permitted, and provided that you do + these two things: +

+
+

a) Accompany the combined library with a copy of the same work based on the + Library, uncombined with any other library facilities. This must be distributed + under the terms of the Sections above. +

+

b) Give prominent notice with the combined library of the fact that part of it + is a work based on the Library, and explaining where to find the accompanying + uncombined form of the same work.

+
+

8. You may not copy, modify, sublicense, link with, or + distribute the Library except as expressly provided under this License. Any + attempt otherwise to copy, modify, sublicense, link with, or distribute the + Library is void, and will automatically terminate your rights under this + License. However, parties who have received copies, or rights, from you under + this License will not have their licenses terminated so long as such parties + remain in full compliance. +

+

9. You are not required to accept this License, since you have + not signed it. However, nothing else grants you permission to modify or + distribute the Library or its derivative works. These actions are prohibited by + law if you do not accept this License. Therefore, by modifying or distributing + the Library (or any work based on the Library), you indicate your acceptance of + this License to do so, and all its terms and conditions for copying, + distributing or modifying the Library or works based on it. +

+

10. Each time you redistribute the Library (or any work based + on the Library), the recipient automatically receives a license from the + original licensor to copy, distribute, link with or modify the Library subject + to these terms and conditions. You may not impose any further restrictions on + the recipients' exercise of the rights granted herein. You are not responsible + for enforcing compliance by third parties with this License. +

+

11. If, as a consequence of a court judgment or allegation of + patent infringement or for any other reason (not limited to patent issues), + conditions are imposed on you (whether by court order, agreement or otherwise) + that contradict the conditions of this License, they do not excuse you from the + conditions of this License. If you cannot distribute so as to satisfy + simultaneously your obligations under this License and any other pertinent + obligations, then as a consequence you may not distribute the Library at all. + For example, if a patent license would not permit royalty-free redistribution + of the Library by all those who receive copies directly or indirectly through + you, then the only way you could satisfy both it and this License would be to + refrain entirely from distribution of the Library. +

+

If any portion of this section is held invalid or unenforceable under any + particular circumstance, the balance of the section is intended to apply, and + the section as a whole is intended to apply in other circumstances. +

+

It is not the purpose of this section to induce you to infringe any patents or + other property right claims or to contest validity of any such claims; this + section has the sole purpose of protecting the integrity of the free software + distribution system which is implemented by public license practices. Many + people have made generous contributions to the wide range of software + distributed through that system in reliance on consistent application of that + system; it is up to the author/donor to decide if he or she is willing to + distribute software through any other system and a licensee cannot impose that + choice. +

+

This section is intended to make thoroughly clear what is believed to be a + consequence of the rest of this License. +

+

12. If the distribution and/or use of the Library is restricted + in certain countries either by patents or by copyrighted interfaces, the + original copyright holder who places the Library under this License may add an + explicit geographical distribution limitation excluding those countries, so + that distribution is permitted only in or among countries not thus excluded. In + such case, this License incorporates the limitation as if written in the body + of this License. +

+

13. The Free Software Foundation may publish revised and/or new + versions of the Lesser General Public License from time to time. Such new + versions will be similar in spirit to the present version, but may differ in + detail to address new problems or concerns.

+

Each version is given a distinguishing version number. If the Library specifies + a version number of this License which applies to it and "any later version", + you have the option of following the terms and conditions either of that + version or of any later version published by the Free Software Foundation. If + the Library does not specify a license version number, you may choose any + version ever published by the Free Software Foundation. +

+

14. If you wish to incorporate parts of the Library into other + free programs whose distribution conditions are incompatible with these, write + to the author to ask for permission. For software which is copyrighted by the + Free Software Foundation, write to the Free Software Foundation; we sometimes + make exceptions for this. Our decision will be guided by the two goals of + preserving the free status of all derivatives of our free software and of + promoting the sharing and reuse of software generally. +

+

NO WARRANTY +

+

15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO + WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT + WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES + PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR + IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE + QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE + DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR + CORRECTION. +

+

16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO + IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR + REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, + INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT + OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS + OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD + PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN + IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES. +

+

END OF TERMS AND CONDITIONS

+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_about/logo_fckeditor.gif b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_about/logo_fckeditor.gif new file mode 100644 index 0000000000000000000000000000000000000000..b7d6bc6fe32cb90cedb27352ac3421ade8549082 GIT binary patch literal 2044 zcma)%`6JT}1Hiw#n9Z@!HdjqKMmDREo}Oyc95ctdo?NSyJF3}S$@AJAu_UBMJuyVC z(H;@X!^~Y_9VC%aPk6|E_V&Dc-{(JgKRxG2{6bhA-7|CETa5$VuBzpY#@%KO9 z%w`-JA0M9=`7KG}Hs00^3=FKwgqfL{U%A@=08lEG|MUNk@fH*W03^WbpX8q>Kt(A{ zWV={t(j_IFrev(K+e1`uq$~23IQr$cxK@QE){SV*oUV(@w~L@#0EaYK{miIG@t-D$ z@F0F54ncw=6KUFDD9&FSk_{IKVuT@j-mq)A#CxtWS6vN-mTn*j4FU?Nsul-A!K9m{ znjo-dwtoUhGsUO=j(06BKgQ6lq&wtMA-9-jRODS=DMnV%KWKY5xQ_abd&40)u37L- z*UzL6tl7#m){yI;V|6_Gb0%bEZiFTF@9L7>4uonP@z>EXHn5_@p?P@Lb`V(I5HG`T z%eyVmQFT#Z3*``%F}#fzP+Opl(tz8F~sSX2L1<=}~uB<0OLmtc$vYXOk;AN?PZ zasnm|c;XTIdE-VcN zC9f)Ew(;-ptp1H`Z-YTKEa8L2fT_BgV6A`8FS8$6SY0f%n(6MHNt zzP~KMmXJ|W|LeC$h5U>1Ca6xp1JPk7cc=V^qEgMXGO?WTSOOIbHqMdL>CR475lP|2wqt^a7w)*(2L}= z-!JVRIZ*R^& zPl$;vp~5ikwU^m zYq%ADUOC}+hf0{$uqqDmDdK0pd?6S=>*&iZ!8zd*`X^qIOmf4Qd-2?eRM=580PEKJ zRoxxYSsK35XFnz8upddARj4eRFg3YFCQJGni;s}LHkqDVeH)1F88V_?YcoI`+_@+l zQZd;p8}bzaYr_FowiynQHpN{%=N7w6`hB?h)KOpatdz09sr)BAWOYQaoST>{54{HvYHh+M%M}%%_5{`+jx5Cl8sX#Q85HQgO+7(Wafr{ECve(Y$ z=XuNZ23a;U2GrIl_-+y(v@UQ?kj@7Td~)pB+d#;jGvZEwHqu*BZQ2`CN||as9XxNM z3Q_hF)UYH4Qe6Qu#RB2yK8}1JR<+%TDvAn|OWDy*&68sjQFN(D*`k`HYPraR#8b3& z(;A@#@@TUkJBQ6&C}rMR$W{L&mElJzlXs-rvXznL4xvoNi5<4no{a2Bb$HvR01Uhg z*IqOvb~^H)YN+#XT|>zFL+mTj+K@ggexk+*g-BB*&(`veHn-t!_=fp>$r`rT0+bR# zlTM*d4$!T%l}E(HQ{Z(CjVQ4+;#}Q%YB#r&2EWBrTNe(lOw2Q@VNI=#HW!kH%B z4n7&`adX1_+*X}eG$=Np&eTZA>QxYoQxJY4-6TEfiTQ}Uu2s{0E7)V!`*ec)biANBIj(-pYf!z9xF7NcMD_il8pg zq;_7T8zFfamRfh#Ois0W}Dj3SS*R;Pdf~XX_XpXJM44|#5 z<4N|DLv|8A`No^yO5BRz&8qLJnc2`?9ly~$Z+ILwy`aP6gsN)odTp}m$v4q00&O)p zV>egJh#i%X%-(m&wG^&^2Ot@MrwwDdl$23++CT5;$9!^?HGIz*+E&LiOJniYZevWR z_t2esTMd0y@cDb>L=Emi0DW$&J?*W3G3^nYU54v(xqP0V5)y3b_uG$AQ& Sj6VMTHl}5%&jAGhhyDxSl!}}H literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_about/logo_fredck.gif b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_about/logo_fredck.gif new file mode 100644 index 0000000000000000000000000000000000000000..3108dd9ec45936ba349dfa30a172d17cde7ea956 GIT binary patch literal 920 zcmZ?wbhEHb3};YbxN5-gW}5G(ogE)HRDC_UFe^^uavPt{(B-ejGK7Tnd_2>N)f8IWLGu{8k^*!G&Z20x; z%DaW}zhB*czc~5ZsilA3K779-`_tB@Hn|7a82VvpPJuN`DM_ufjjqOnPz zueQxaxH!1Er=q=t@YeT*kA&Ls+zQ$(nSoTyHss&097b zY}&d-NoUXAeL5`qd&NW9b@xe!>J{b7*KXaurmKHdCxqp;V92!) zp{x9jG6^?tGpR5#%Ibdm{^RGj^AGd|?&$H=tp0YW!IY!o*3Q*!i>5X3Yx{5*Fg(1; z&Ber#BcQN>%Z-ugm+Jso55L4C1By%+pW1e8hdth7AtK1pOC($ zbxoR}Z(By*J;oW+7qxDj^>{~a2IGWQ$E?>EBD_6)o91$Dn8Z{Q#mmUJPETdZiffM= zt+wd!g=jCI8hufVSx2HOJy-VXx{y1|Y7MU(jTbNZJ$H5Y)>+}&IeZ`2y1m(ObfTV~ zgF}F?-qr%U!--{#SG>%#Wkt8xge+jbZ9Hvi;pbzf+534@d0E!FH5OlIl#(;``0!|h zx%S5R2iMrXY`9*x_q5g8qIVm*h5L1MjQD12Onvd-P3)K6h^PB=@11KbXFPPF;K}-j z!P;33Hep&!Z|c_xg|6@y*H;l}GL`?Z@qkKbf%<&za><6Uv`~u`ycr=L9=uG?LW~)C z1LLjEk3evQ**BpB$sI>3q38|{HD_iDHNeN&Ks(N=)U5+_n!NFOLRg5PVq+1+ln9~^- snXb(x!IinBfX6&jSu){+#-bT + + + + Anchor Properties + + + + + + + + + + +
+ + + + +
+ Anchor Name
+ +
+
+ + \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_button.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_button.html new file mode 100644 index 00000000..906e5a42 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_button.html @@ -0,0 +1,103 @@ + + + + + Button Properties + + + + + + + + + + +
+ + + + + + + + + + +
+ Name
+ +
+ Text (Value)
+ +
+ Type
+ +
+
+ + \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_checkbox.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_checkbox.html new file mode 100644 index 00000000..37a7eb0b --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_checkbox.html @@ -0,0 +1,103 @@ + + + + + Checkbox Properties + + + + + + + + + + +
+ + + + + + + + + + +
+ Name
+ +
+ Value
+ +
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_colorselector.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_colorselector.html new file mode 100644 index 00000000..031f866f --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_colorselector.html @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + +
+ + + + + +
+ +
+
+ Highlight +
+
 
+ Selected +
+ +
+ +
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_docprops.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_docprops.html new file mode 100644 index 00000000..ab6e3f4a --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_docprops.html @@ -0,0 +1,570 @@ + + + + + Document Properties + + + + + + + + + + + + + +
+
+ Page Title
+ +
+ + + + + + +
+ Language Direction
+ +
    + Language Code
+ +
+
+ + + + + + + + + + + + + + +
Character Set Encoding
+ +
    + Other Character Set Encoding
+ +
 
+ Document Type Heading
+ +
+ Other Document Type Heading
+ +
+
+ +
+ + + +
+ + \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_docprops/fck_document_preview.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_docprops/fck_document_preview.html new file mode 100644 index 00000000..c620010e --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_docprops/fck_document_preview.html @@ -0,0 +1,109 @@ + + + + + Document Properties - Preview + + + + + + + + + + + + + + +
+ Normal Text +
+ Visited Link + + Active Link +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_find.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_find.html new file mode 100644 index 00000000..4c0b5a8a --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_find.html @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + +
+   + + + + +
+   +
+ +
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_flash.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_flash.html new file mode 100644 index 00000000..d7f6cfdd --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_flash.html @@ -0,0 +1,142 @@ + + + + + Flash Properties + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + +
URL +
+
+
+ + + + + + +
+ Width
+ +
  + Height
+ +
+
+ + + + +
+ + + + + + + +
Preview
+
+
+
+ + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_form.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_form.html new file mode 100644 index 00000000..b6c05d56 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_form.html @@ -0,0 +1,101 @@ + + + + + Checkbox Properties + + + + + + + + + + +
+ + + + + + + + + + +
+ Name
+ +
+ Action
+ +
+ Method
+ +
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_hiddenfield.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_hiddenfield.html new file mode 100644 index 00000000..1bcfc437 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_hiddenfield.html @@ -0,0 +1,91 @@ + + + + + Hidden Field Properties + + + + + + + + + + +
+ + + + + + + +
+ Name
+ +
+ Value
+ +
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_image.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_image.html new file mode 100644 index 00000000..78cf4343 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_image.html @@ -0,0 +1,225 @@ + + + + + Image Properties + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + +
+ URL +
+ +
+
+ Short Description
+
+
+ + + + + + +
+
+ + + + + + + + + + +
Width  + +
+
+
Height  +
+
+ + + + + + + + + + + + + + + + + +
Border  +
HSpace  +
VSpace  +
Align  +
+
    + + + + + + + +
Preview
+ +
+
+
+
+ + + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_image/fck_image.js b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_image/fck_image.js new file mode 100644 index 00000000..2b5b4ff3 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_image/fck_image.js @@ -0,0 +1,475 @@ +/* + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: fck_image.js + * Scripts related to the Image dialog window (see fck_image.html). + * + * File Authors: + * Frederico Caldeira Knabben (fredck@fckeditor.net) + */ + +var oEditor = window.parent.InnerDialogLoaded() ; +var FCK = oEditor.FCK ; +var FCKLang = oEditor.FCKLang ; +var FCKConfig = oEditor.FCKConfig ; +var FCKDebug = oEditor.FCKDebug ; + +var bImageButton = ( document.location.search.length > 0 && document.location.search.substr(1) == 'ImageButton' ) ; + +//#### Dialog Tabs + +// Set the dialog tabs. +window.parent.AddTab( 'Info', FCKLang.DlgImgInfoTab ) ; + +if ( !bImageButton && !FCKConfig.ImageDlgHideLink ) + window.parent.AddTab( 'Link', FCKLang.DlgImgLinkTab ) ; + +if ( FCKConfig.ImageUpload ) + window.parent.AddTab( 'Upload', FCKLang.DlgLnkUpload ) ; + +if ( !FCKConfig.ImageDlgHideAdvanced ) + window.parent.AddTab( 'Advanced', FCKLang.DlgAdvancedTag ) ; + +// Function called when a dialog tag is selected. +function OnDialogTabChange( tabCode ) +{ + ShowE('divInfo' , ( tabCode == 'Info' ) ) ; + ShowE('divLink' , ( tabCode == 'Link' ) ) ; + ShowE('divUpload' , ( tabCode == 'Upload' ) ) ; + ShowE('divAdvanced' , ( tabCode == 'Advanced' ) ) ; +} + +// Get the selected image (if available). +var oImage = FCK.Selection.GetSelectedElement() ; + +if ( oImage && oImage.tagName != 'IMG' && !( oImage.tagName == 'INPUT' && oImage.type == 'image' ) ) + oImage = null ; + +// Get the active link. +var oLink = FCK.Selection.MoveToAncestorNode( 'A' ) ; + +var oImageOriginal ; + +function UpdateOriginal( resetSize ) +{ + if ( !eImgPreview ) + return ; + + oImageOriginal = document.createElement( 'IMG' ) ; // new Image() ; + + if ( resetSize ) + { + oImageOriginal.onload = function() + { + this.onload = null ; + ResetSizes() ; + } + } + + oImageOriginal.src = eImgPreview.src ; +} + +var bPreviewInitialized ; + +window.onload = function() +{ + // Translate the dialog box texts. + oEditor.FCKLanguageManager.TranslatePage(document) ; + + GetE('btnLockSizes').title = FCKLang.DlgImgLockRatio ; + GetE('btnResetSize').title = FCKLang.DlgBtnResetSize ; + + // Load the selected element information (if any). + LoadSelection() ; + + // Show/Hide the "Browse Server" button. + GetE('tdBrowse').style.display = FCKConfig.ImageBrowser ? '' : 'none' ; + GetE('divLnkBrowseServer').style.display = FCKConfig.LinkBrowser ? '' : 'none' ; + + UpdateOriginal() ; + + // Set the actual uploader URL. + if ( FCKConfig.ImageUpload ) + GetE('frmUpload').action = FCKConfig.ImageUploadURL ; + + window.parent.SetAutoSize( true ) ; + + // Activate the "OK" button. + window.parent.SetOkButton( true ) ; +} + +function LoadSelection() +{ + if ( ! oImage ) return ; + + var sUrl = GetAttribute( oImage, '_fcksavedurl', '' ) ; + if ( sUrl.length == 0 ) + sUrl = GetAttribute( oImage, 'src', '' ) ; + + // TODO: Wait stable version and remove the following commented lines. +// if ( sUrl.startsWith( FCK.BaseUrl ) ) +// sUrl = sUrl.remove( 0, FCK.BaseUrl.length ) ; + + GetE('txtUrl').value = sUrl ; + GetE('txtAlt').value = GetAttribute( oImage, 'alt', '' ) ; + GetE('txtVSpace').value = GetAttribute( oImage, 'vspace', '' ) ; + GetE('txtHSpace').value = GetAttribute( oImage, 'hspace', '' ) ; + GetE('txtBorder').value = GetAttribute( oImage, 'border', '' ) ; + GetE('cmbAlign').value = GetAttribute( oImage, 'align', '' ) ; + + var iWidth, iHeight ; + + var regexSize = /^\s*(\d+)px\s*$/i ; + + if ( oImage.style.width ) + { + var aMatch = oImage.style.width.match( regexSize ) ; + if ( aMatch ) + { + iWidth = aMatch[1] ; + oImage.style.width = '' ; + } + } + + if ( oImage.style.height ) + { + var aMatch = oImage.style.height.match( regexSize ) ; + if ( aMatch ) + { + iHeight = aMatch[1] ; + oImage.style.height = '' ; + } + } + + GetE('txtWidth').value = iWidth ? iWidth : GetAttribute( oImage, "width", '' ) ; + GetE('txtHeight').value = iHeight ? iHeight : GetAttribute( oImage, "height", '' ) ; + + // Get Advances Attributes + GetE('txtAttId').value = oImage.id ; + GetE('cmbAttLangDir').value = oImage.dir ; + GetE('txtAttLangCode').value = oImage.lang ; + GetE('txtAttTitle').value = oImage.title ; + GetE('txtAttClasses').value = oImage.getAttribute('class',2) || '' ; + GetE('txtLongDesc').value = oImage.longDesc ; + + if ( oEditor.FCKBrowserInfo.IsIE ) + GetE('txtAttStyle').value = oImage.style.cssText ; + else + GetE('txtAttStyle').value = oImage.getAttribute('style',2) ; + + if ( oLink ) + { + var sUrl = GetAttribute( oLink, '_fcksavedurl', '' ) ; + if ( sUrl.length == 0 ) + sUrl = oLink.getAttribute('href',2) ; + + GetE('txtLnkUrl').value = sUrl ; + GetE('cmbLnkTarget').value = oLink.target ; + } + + UpdatePreview() ; +} + +//#### The OK button was hit. +function Ok() +{ + if ( GetE('txtUrl').value.length == 0 ) + { + window.parent.SetSelectedTab( 'Info' ) ; + GetE('txtUrl').focus() ; + + alert( FCKLang.DlgImgAlertUrl ) ; + + return false ; + } + + var bHasImage = ( oImage != null ) ; + + if ( bHasImage && bImageButton && oImage.tagName == 'IMG' ) + { + if ( confirm( 'Do you want to transform the selected image on a image button?' ) ) + oImage = null ; + } + else if ( bHasImage && !bImageButton && oImage.tagName == 'INPUT' ) + { + if ( confirm( 'Do you want to transform the selected image button on a simple image?' ) ) + oImage = null ; + } + + if ( !bHasImage ) + { + if ( bImageButton ) + { + oImage = FCK.EditorDocument.createElement( 'INPUT' ) ; + oImage.type = 'image' ; + oImage = FCK.InsertElementAndGetIt( oImage ) ; + } + else + oImage = FCK.CreateElement( 'IMG' ) ; + } + else + oEditor.FCKUndo.SaveUndoStep() ; + + UpdateImage( oImage ) ; + + var sLnkUrl = GetE('txtLnkUrl').value.trim() ; + + if ( sLnkUrl.length == 0 ) + { + if ( oLink ) + FCK.ExecuteNamedCommand( 'Unlink' ) ; + } + else + { + if ( oLink ) // Modifying an existent link. + oLink.href = sLnkUrl ; + else // Creating a new link. + { + if ( !bHasImage ) + oEditor.FCKSelection.SelectNode( oImage ) ; + + oLink = oEditor.FCK.CreateLink( sLnkUrl ) ; + + if ( !bHasImage ) + { + oEditor.FCKSelection.SelectNode( oLink ) ; + oEditor.FCKSelection.Collapse( false ) ; + } + } + + SetAttribute( oLink, '_fcksavedurl', sLnkUrl ) ; + SetAttribute( oLink, 'target', GetE('cmbLnkTarget').value ) ; + } + + return true ; +} + +function UpdateImage( e, skipId ) +{ + e.src = GetE('txtUrl').value ; + SetAttribute( e, "_fcksavedurl", GetE('txtUrl').value ) ; + SetAttribute( e, "alt" , GetE('txtAlt').value ) ; + SetAttribute( e, "width" , GetE('txtWidth').value ) ; + SetAttribute( e, "height", GetE('txtHeight').value ) ; + SetAttribute( e, "vspace", GetE('txtVSpace').value ) ; + SetAttribute( e, "hspace", GetE('txtHSpace').value ) ; + SetAttribute( e, "border", GetE('txtBorder').value ) ; + SetAttribute( e, "align" , GetE('cmbAlign').value ) ; + + // Advances Attributes + + if ( ! skipId ) + SetAttribute( e, 'id', GetE('txtAttId').value ) ; + + SetAttribute( e, 'dir' , GetE('cmbAttLangDir').value ) ; + SetAttribute( e, 'lang' , GetE('txtAttLangCode').value ) ; + SetAttribute( e, 'title' , GetE('txtAttTitle').value ) ; + SetAttribute( e, 'class' , GetE('txtAttClasses').value ) ; + SetAttribute( e, 'longDesc' , GetE('txtLongDesc').value ) ; + + if ( oEditor.FCKBrowserInfo.IsIE ) + e.style.cssText = GetE('txtAttStyle').value ; + else + SetAttribute( e, 'style', GetE('txtAttStyle').value ) ; +} + +var eImgPreview ; +var eImgPreviewLink ; + +function SetPreviewElements( imageElement, linkElement ) +{ + eImgPreview = imageElement ; + eImgPreviewLink = linkElement ; + + UpdatePreview() ; + UpdateOriginal() ; + + bPreviewInitialized = true ; +} + +function UpdatePreview() +{ + if ( !eImgPreview || !eImgPreviewLink ) + return ; + + if ( GetE('txtUrl').value.length == 0 ) + eImgPreviewLink.style.display = 'none' ; + else + { + UpdateImage( eImgPreview, true ) ; + + if ( GetE('txtLnkUrl').value.trim().length > 0 ) + eImgPreviewLink.href = 'javascript:void(null);' ; + else + SetAttribute( eImgPreviewLink, 'href', '' ) ; + + eImgPreviewLink.style.display = '' ; + } +} + +var bLockRatio = true ; + +function SwitchLock( lockButton ) +{ + bLockRatio = !bLockRatio ; + lockButton.className = bLockRatio ? 'BtnLocked' : 'BtnUnlocked' ; + lockButton.title = bLockRatio ? 'Lock sizes' : 'Unlock sizes' ; + + if ( bLockRatio ) + { + if ( GetE('txtWidth').value.length > 0 ) + OnSizeChanged( 'Width', GetE('txtWidth').value ) ; + else + OnSizeChanged( 'Height', GetE('txtHeight').value ) ; + } +} + +// Fired when the width or height input texts change +function OnSizeChanged( dimension, value ) +{ + // Verifies if the aspect ration has to be mantained + if ( oImageOriginal && bLockRatio ) + { + var e = dimension == 'Width' ? GetE('txtHeight') : GetE('txtWidth') ; + + if ( value.length == 0 || isNaN( value ) ) + { + e.value = '' ; + return ; + } + + if ( dimension == 'Width' ) + value = value == 0 ? 0 : Math.round( oImageOriginal.height * ( value / oImageOriginal.width ) ) ; + else + value = value == 0 ? 0 : Math.round( oImageOriginal.width * ( value / oImageOriginal.height ) ) ; + + if ( !isNaN( value ) ) + e.value = value ; + } + + UpdatePreview() ; +} + +// Fired when the Reset Size button is clicked +function ResetSizes() +{ + if ( ! oImageOriginal ) return ; + + GetE('txtWidth').value = oImageOriginal.width ; + GetE('txtHeight').value = oImageOriginal.height ; + + UpdatePreview() ; +} + +function BrowseServer() +{ + OpenServerBrowser( + 'Image', + FCKConfig.ImageBrowserURL, + FCKConfig.ImageBrowserWindowWidth, + FCKConfig.ImageBrowserWindowHeight ) ; +} + +function LnkBrowseServer() +{ + OpenServerBrowser( + 'Link', + FCKConfig.LinkBrowserURL, + FCKConfig.LinkBrowserWindowWidth, + FCKConfig.LinkBrowserWindowHeight ) ; +} + +function OpenServerBrowser( type, url, width, height ) +{ + sActualBrowser = type ; + OpenFileBrowser( url, width, height ) ; +} + +var sActualBrowser ; + +function SetUrl( url, width, height, alt ) +{ + if ( sActualBrowser == 'Link' ) + { + GetE('txtLnkUrl').value = url ; + UpdatePreview() ; + } + else + { + GetE('txtUrl').value = url ; + GetE('txtWidth').value = width ? width : '' ; + GetE('txtHeight').value = height ? height : '' ; + + if ( alt ) + GetE('txtAlt').value = alt; + + UpdatePreview() ; + UpdateOriginal( true ) ; + } + + window.parent.SetSelectedTab( 'Info' ) ; +} + +function OnUploadCompleted( errorNumber, fileUrl, fileName, customMsg ) +{ + switch ( errorNumber ) + { + case 0 : // No errors + alert( 'Your file has been successfully uploaded' ) ; + break ; + case 1 : // Custom error + alert( customMsg ) ; + return ; + case 101 : // Custom warning + alert( customMsg ) ; + break ; + case 201 : + alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ; + break ; + case 202 : + alert( 'Invalid file type' ) ; + return ; + case 203 : + alert( "Security error. You probably don't have enough permissions to upload. Please check your server." ) ; + return ; + default : + alert( 'Error on file upload. Error number: ' + errorNumber ) ; + return ; + } + + sActualBrowser = '' + SetUrl( fileUrl ) ; + GetE('frmUpload').reset() ; +} + +var oUploadAllowedExtRegex = new RegExp( FCKConfig.ImageUploadAllowedExtensions, 'i' ) ; +var oUploadDeniedExtRegex = new RegExp( FCKConfig.ImageUploadDeniedExtensions, 'i' ) ; + +function CheckUpload() +{ + var sFile = GetE('txtUploadFile').value ; + + if ( sFile.length == 0 ) + { + alert( 'Please select a file to upload' ) ; + return false ; + } + + if ( ( FCKConfig.ImageUploadAllowedExtensions.length > 0 && !oUploadAllowedExtRegex.test( sFile ) ) || + ( FCKConfig.ImageUploadDeniedExtensions.length > 0 && oUploadDeniedExtRegex.test( sFile ) ) ) + { + OnUploadCompleted( 202 ) ; + return false ; + } + + return true ; +} \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_image/fck_image_preview.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_image/fck_image_preview.html new file mode 100644 index 00000000..d63cf508 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_image/fck_image_preview.html @@ -0,0 +1,61 @@ + + + + + + + + + + + + Lorem + ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas feugiat consequat + diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis + vitae, nulla. Aenean dictum lacinia tortor. Nunc iaculis, nibh non iaculis + aliquam, orci felis euismod neque, sed ornare massa mauris sed velit. Nulla + pretium mi et risus. Fusce mi pede, tempor id, cursus ac, ullamcorper nec, + enim. Sed tortor. Curabitur molestie. Duis velit augue, condimentum at, + ultrices a, luctus ut, orci. Donec pellentesque egestas eros. Integer cursus, + augue in cursus faucibus, eros pede bibendum sem, in tempus tellus justo quis + ligula. Etiam eget tortor. Vestibulum rutrum, est ut placerat elementum, lectus + nisl aliquam velit, tempor aliquam eros nunc nonummy metus. In eros metus, + gravida a, gravida sed, lobortis id, turpis. Ut ultrices, ipsum at venenatis + fringilla, sem nulla lacinia tellus, eget aliquet turpis mauris non enim. Nam + turpis. Suspendisse lacinia. Curabitur ac tortor ut ipsum egestas elementum. + Nunc imperdiet gravida mauris. + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_link.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_link.html new file mode 100644 index 00000000..33a56b63 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_link.html @@ -0,0 +1,289 @@ + + + + + Link Properties + + + + + + + + + + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_link/fck_link.js b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_link/fck_link.js new file mode 100644 index 00000000..f17e4b37 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_link/fck_link.js @@ -0,0 +1,588 @@ +/* + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: fck_link.js + * Scripts related to the Link dialog window (see fck_link.html). + * + * File Authors: + * Frederico Caldeira Knabben (fredck@fckeditor.net) + */ + +var oEditor = window.parent.InnerDialogLoaded() ; +var FCK = oEditor.FCK ; +var FCKLang = oEditor.FCKLang ; +var FCKConfig = oEditor.FCKConfig ; + +//#### Dialog Tabs + +// Set the dialog tabs. +window.parent.AddTab( 'Info', FCKLang.DlgLnkInfoTab ) ; + +if ( !FCKConfig.LinkDlgHideTarget ) + window.parent.AddTab( 'Target', FCKLang.DlgLnkTargetTab, true ) ; + +if ( FCKConfig.LinkUpload ) + window.parent.AddTab( 'Upload', FCKLang.DlgLnkUpload, true ) ; + +if ( !FCKConfig.LinkDlgHideAdvanced ) + window.parent.AddTab( 'Advanced', FCKLang.DlgAdvancedTag ) ; + +// Function called when a dialog tag is selected. +function OnDialogTabChange( tabCode ) +{ + ShowE('divInfo' , ( tabCode == 'Info' ) ) ; + ShowE('divTarget' , ( tabCode == 'Target' ) ) ; + ShowE('divUpload' , ( tabCode == 'Upload' ) ) ; + ShowE('divAttribs' , ( tabCode == 'Advanced' ) ) ; +} + +//#### Regular Expressions library. +var oRegex = new Object() ; + +oRegex.UriProtocol = new RegExp('') ; +oRegex.UriProtocol.compile( '^(((http|https|ftp|news):\/\/)|mailto:)', 'gi' ) ; + +oRegex.UrlOnChangeProtocol = new RegExp('') ; +oRegex.UrlOnChangeProtocol.compile( '^(http|https|ftp|news)://(?=.)', 'gi' ) ; + +oRegex.UrlOnChangeTestOther = new RegExp('') ; +//oRegex.UrlOnChangeTestOther.compile( '^(javascript:|#|/)', 'gi' ) ; +oRegex.UrlOnChangeTestOther.compile( '^((javascript:)|[#/\.])', 'gi' ) ; + +oRegex.ReserveTarget = new RegExp('') ; +oRegex.ReserveTarget.compile( '^_(blank|self|top|parent)$', 'i' ) ; + +oRegex.PopupUri = new RegExp('') ; +oRegex.PopupUri.compile( "^javascript:void\\(\\s*window.open\\(\\s*'([^']+)'\\s*,\\s*(?:'([^']*)'|null)\\s*,\\s*'([^']*)'\\s*\\)\\s*\\)\\s*$" ) ; + +oRegex.PopupFeatures = new RegExp('') ; +oRegex.PopupFeatures.compile( '(?:^|,)([^=]+)=(\\d+|yes|no)', 'gi' ) ; + +//#### Parser Functions + +var oParser = new Object() ; + +oParser.ParseEMailUrl = function( emailUrl ) +{ + // Initializes the EMailInfo object. + var oEMailInfo = new Object() ; + oEMailInfo.Address = '' ; + oEMailInfo.Subject = '' ; + oEMailInfo.Body = '' ; + + var oParts = emailUrl.match( /^([^\?]+)\??(.+)?/ ) ; + if ( oParts ) + { + // Set the e-mail address. + oEMailInfo.Address = oParts[1] ; + + // Look for the optional e-mail parameters. + if ( oParts[2] ) + { + var oMatch = oParts[2].match( /(^|&)subject=([^&]+)/i ) ; + if ( oMatch ) oEMailInfo.Subject = unescape( oMatch[2] ) ; + + oMatch = oParts[2].match( /(^|&)body=([^&]+)/i ) ; + if ( oMatch ) oEMailInfo.Body = unescape( oMatch[2] ) ; + } + } + + return oEMailInfo ; +} + +oParser.CreateEMailUri = function( address, subject, body ) +{ + var sBaseUri = 'mailto:' + address ; + + var sParams = '' ; + + if ( subject.length > 0 ) + sParams = '?subject=' + escape( subject ) ; + + if ( body.length > 0 ) + { + sParams += ( sParams.length == 0 ? '?' : '&' ) ; + sParams += 'body=' + escape( body ) ; + } + + return sBaseUri + sParams ; +} + +//#### Initialization Code + +// oLink: The actual selected link in the editor. +var oLink = FCK.Selection.MoveToAncestorNode( 'A' ) ; +if ( oLink ) + FCK.Selection.SelectNode( oLink ) ; + +window.onload = function() +{ + // Translate the dialog box texts. + oEditor.FCKLanguageManager.TranslatePage(document) ; + + // Fill the Anchor Names and Ids combos. + LoadAnchorNamesAndIds() ; + + // Load the selected link information (if any). + LoadSelection() ; + + // Update the dialog box. + SetLinkType( GetE('cmbLinkType').value ) ; + + // Show/Hide the "Browse Server" button. + GetE('divBrowseServer').style.display = FCKConfig.LinkBrowser ? '' : 'none' ; + + // Show the initial dialog content. + GetE('divInfo').style.display = '' ; + + // Set the actual uploader URL. + if ( FCKConfig.LinkUpload ) + GetE('frmUpload').action = FCKConfig.LinkUploadURL ; + + // Activate the "OK" button. + window.parent.SetOkButton( true ) ; +} + +var bHasAnchors ; + +function LoadAnchorNamesAndIds() +{ + // Since version 2.0, the anchors are replaced in the DOM by IMGs so the user see the icon + // to edit them. So, we must look for that images now. + var aAnchors = new Array() ; + + var oImages = oEditor.FCK.EditorDocument.getElementsByTagName( 'IMG' ) ; + for( var i = 0 ; i < oImages.length ; i++ ) + { + if ( oImages[i].getAttribute('_fckanchor') ) + aAnchors[ aAnchors.length ] = oEditor.FCK.GetRealElement( oImages[i] ) ; + } + + var aIds = oEditor.FCKTools.GetAllChildrenIds( oEditor.FCK.EditorDocument.body ) ; + + bHasAnchors = ( aAnchors.length > 0 || aIds.length > 0 ) ; + + for ( var i = 0 ; i < aAnchors.length ; i++ ) + { + var sName = aAnchors[i].name ; + if ( sName && sName.length > 0 ) + oEditor.FCKTools.AddSelectOption( document, GetE('cmbAnchorName'), sName, sName ) ; + } + + for ( var i = 0 ; i < aIds.length ; i++ ) + { + oEditor.FCKTools.AddSelectOption( document, GetE('cmbAnchorId'), aIds[i], aIds[i] ) ; + } + + ShowE( 'divSelAnchor' , bHasAnchors ) ; + ShowE( 'divNoAnchor' , !bHasAnchors ) ; +} + +function LoadSelection() +{ + if ( !oLink ) return ; + + var sType = 'url' ; + + // Get the actual Link href. + var sHRef = oLink.getAttribute( '_fcksavedurl' ) ; + if ( !sHRef || sHRef.length == 0 ) + sHRef = oLink.getAttribute( 'href' , 2 ) + '' ; + + // TODO: Wait stable version and remove the following commented lines. +// if ( sHRef.startsWith( FCK.BaseUrl ) ) +// sHRef = sHRef.remove( 0, FCK.BaseUrl.length ) ; + + // Look for a popup javascript link. + var oPopupMatch = oRegex.PopupUri.exec( sHRef ) ; + if( oPopupMatch ) + { + GetE('cmbTarget').value = 'popup' ; + sHRef = oPopupMatch[1] ; + FillPopupFields( oPopupMatch[2], oPopupMatch[3] ) ; + SetTarget( 'popup' ) ; + } + + // Search for the protocol. + var sProtocol = oRegex.UriProtocol.exec( sHRef ) ; + + if ( sProtocol ) + { + sProtocol = sProtocol[0].toLowerCase() ; + GetE('cmbLinkProtocol').value = sProtocol ; + + // Remove the protocol and get the remainig URL. + var sUrl = sHRef.replace( oRegex.UriProtocol, '' ) ; + + if ( sProtocol == 'mailto:' ) // It is an e-mail link. + { + sType = 'email' ; + + var oEMailInfo = oParser.ParseEMailUrl( sUrl ) ; + GetE('txtEMailAddress').value = oEMailInfo.Address ; + GetE('txtEMailSubject').value = oEMailInfo.Subject ; + GetE('txtEMailBody').value = oEMailInfo.Body ; + } + else // It is a normal link. + { + sType = 'url' ; + GetE('txtUrl').value = sUrl ; + } + } + else if ( sHRef.substr(0,1) == '#' && sHRef.length > 1 ) // It is an anchor link. + { + sType = 'anchor' ; + GetE('cmbAnchorName').value = GetE('cmbAnchorId').value = sHRef.substr(1) ; + } + else // It is another type of link. + { + sType = 'url' ; + + GetE('cmbLinkProtocol').value = '' ; + GetE('txtUrl').value = sHRef ; + } + + if ( !oPopupMatch ) + { + // Get the target. + var sTarget = oLink.target ; + + if ( sTarget && sTarget.length > 0 ) + { + if ( oRegex.ReserveTarget.test( sTarget ) ) + { + sTarget = sTarget.toLowerCase() ; + GetE('cmbTarget').value = sTarget ; + } + else + GetE('cmbTarget').value = 'frame' ; + GetE('txtTargetFrame').value = sTarget ; + } + } + + // Get Advances Attributes + GetE('txtAttId').value = oLink.id ; + GetE('txtAttName').value = oLink.name ; + GetE('cmbAttLangDir').value = oLink.dir ; + GetE('txtAttLangCode').value = oLink.lang ; + GetE('txtAttAccessKey').value = oLink.accessKey ; + GetE('txtAttTabIndex').value = oLink.tabIndex <= 0 ? '' : oLink.tabIndex ; + GetE('txtAttTitle').value = oLink.title ; + GetE('txtAttContentType').value = oLink.type ; + GetE('txtAttCharSet').value = oLink.charset ; + + if ( oEditor.FCKBrowserInfo.IsIE ) + { + GetE('txtAttClasses').value = oLink.getAttribute('className',2) || '' ; + GetE('txtAttStyle').value = oLink.style.cssText ; + } + else + { + GetE('txtAttClasses').value = oLink.getAttribute('class',2) || '' ; + GetE('txtAttStyle').value = oLink.getAttribute('style',2) ; + } + + // Update the Link type combo. + GetE('cmbLinkType').value = sType ; +} + +//#### Link type selection. +function SetLinkType( linkType ) +{ + ShowE('divLinkTypeUrl' , (linkType == 'url') ) ; + ShowE('divLinkTypeAnchor' , (linkType == 'anchor') ) ; + ShowE('divLinkTypeEMail' , (linkType == 'email') ) ; + + if ( !FCKConfig.LinkDlgHideTarget ) + window.parent.SetTabVisibility( 'Target' , (linkType == 'url') ) ; + + if ( FCKConfig.LinkUpload ) + window.parent.SetTabVisibility( 'Upload' , (linkType == 'url') ) ; + + if ( !FCKConfig.LinkDlgHideAdvanced ) + window.parent.SetTabVisibility( 'Advanced' , (linkType != 'anchor' || bHasAnchors) ) ; + + if ( linkType == 'email' ) + window.parent.SetAutoSize( true ) ; +} + +//#### Target type selection. +function SetTarget( targetType ) +{ + GetE('tdTargetFrame').style.display = ( targetType == 'popup' ? 'none' : '' ) ; + GetE('tdPopupName').style.display = + GetE('tablePopupFeatures').style.display = ( targetType == 'popup' ? '' : 'none' ) ; + + switch ( targetType ) + { + case "_blank" : + case "_self" : + case "_parent" : + case "_top" : + GetE('txtTargetFrame').value = targetType ; + break ; + case "" : + GetE('txtTargetFrame').value = '' ; + break ; + } + + if ( targetType == 'popup' ) + window.parent.SetAutoSize( true ) ; +} + +//#### Called while the user types the URL. +function OnUrlChange() +{ + var sUrl = GetE('txtUrl').value ; + var sProtocol = oRegex.UrlOnChangeProtocol.exec( sUrl ) ; + + if ( sProtocol ) + { + sUrl = sUrl.substr( sProtocol[0].length ) ; + GetE('txtUrl').value = sUrl ; + GetE('cmbLinkProtocol').value = sProtocol[0].toLowerCase() ; + } + else if ( oRegex.UrlOnChangeTestOther.test( sUrl ) ) + { + GetE('cmbLinkProtocol').value = '' ; + } +} + +//#### Called while the user types the target name. +function OnTargetNameChange() +{ + var sFrame = GetE('txtTargetFrame').value ; + + if ( sFrame.length == 0 ) + GetE('cmbTarget').value = '' ; + else if ( oRegex.ReserveTarget.test( sFrame ) ) + GetE('cmbTarget').value = sFrame.toLowerCase() ; + else + GetE('cmbTarget').value = 'frame' ; +} + +//#### Builds the javascript URI to open a popup to the specified URI. +function BuildPopupUri( uri ) +{ + var oReg = new RegExp( "'", "g" ) ; + var sWindowName = "'" + GetE('txtPopupName').value.replace(oReg, "\\'") + "'" ; + + var sFeatures = '' ; + var aChkFeatures = document.getElementsByName('chkFeature') ; + for ( var i = 0 ; i < aChkFeatures.length ; i++ ) + { + if ( i > 0 ) sFeatures += ',' ; + sFeatures += aChkFeatures[i].value + '=' + ( aChkFeatures[i].checked ? 'yes' : 'no' ) ; + } + + if ( GetE('txtPopupWidth').value.length > 0 ) sFeatures += ',width=' + GetE('txtPopupWidth').value ; + if ( GetE('txtPopupHeight').value.length > 0 ) sFeatures += ',height=' + GetE('txtPopupHeight').value ; + if ( GetE('txtPopupLeft').value.length > 0 ) sFeatures += ',left=' + GetE('txtPopupLeft').value ; + if ( GetE('txtPopupTop').value.length > 0 ) sFeatures += ',top=' + GetE('txtPopupTop').value ; + + return ( "javascript:void(window.open('" + uri + "'," + sWindowName + ",'" + sFeatures + "'))" ) ; +} + +//#### Fills all Popup related fields. +function FillPopupFields( windowName, features ) +{ + if ( windowName ) + GetE('txtPopupName').value = windowName ; + + var oFeatures = new Object() ; + var oFeaturesMatch ; + while( ( oFeaturesMatch = oRegex.PopupFeatures.exec( features ) ) != null ) + { + var sValue = oFeaturesMatch[2] ; + if ( sValue == ( 'yes' || '1' ) ) + oFeatures[ oFeaturesMatch[1] ] = true ; + else if ( ! isNaN( sValue ) && sValue != 0 ) + oFeatures[ oFeaturesMatch[1] ] = sValue ; + } + + // Update all features check boxes. + var aChkFeatures = document.getElementsByName('chkFeature') ; + for ( var i = 0 ; i < aChkFeatures.length ; i++ ) + { + if ( oFeatures[ aChkFeatures[i].value ] ) + aChkFeatures[i].checked = true ; + } + + // Update position and size text boxes. + if ( oFeatures['width'] ) GetE('txtPopupWidth').value = oFeatures['width'] ; + if ( oFeatures['height'] ) GetE('txtPopupHeight').value = oFeatures['height'] ; + if ( oFeatures['left'] ) GetE('txtPopupLeft').value = oFeatures['left'] ; + if ( oFeatures['top'] ) GetE('txtPopupTop').value = oFeatures['top'] ; +} + +//#### The OK button was hit. +function Ok() +{ + var sUri ; + + switch ( GetE('cmbLinkType').value ) + { + case 'url' : + sUri = GetE('txtUrl').value ; + + if ( sUri.length == 0 ) + { + alert( FCKLang.DlnLnkMsgNoUrl ) ; + return false ; + } + + sUri = GetE('cmbLinkProtocol').value + sUri ; + + if( GetE('cmbTarget').value == 'popup' ) + sUri = BuildPopupUri( sUri ) ; + + break ; + + case 'email' : + sUri = GetE('txtEMailAddress').value ; + + if ( sUri.length == 0 ) + { + alert( FCKLang.DlnLnkMsgNoEMail ) ; + return false ; + } + + sUri = oParser.CreateEMailUri( + sUri, + GetE('txtEMailSubject').value, + GetE('txtEMailBody').value ) ; + break ; + + case 'anchor' : + var sAnchor = GetE('cmbAnchorName').value ; + if ( sAnchor.length == 0 ) sAnchor = GetE('cmbAnchorId').value ; + + if ( sAnchor.length == 0 ) + { + alert( FCKLang.DlnLnkMsgNoAnchor ) ; + return false ; + } + + sUri = '#' + sAnchor ; + break ; + } + + if ( oLink ) // Modifying an existent link. + { + oEditor.FCKUndo.SaveUndoStep() ; + oLink.href = sUri ; + } + else // Creating a new link. + { + oLink = oEditor.FCK.CreateLink( sUri ) ; + if ( ! oLink ) + return true ; + } + + SetAttribute( oLink, '_fcksavedurl', sUri ) ; + + // Target + if( GetE('cmbTarget').value != 'popup' ) + SetAttribute( oLink, 'target', GetE('txtTargetFrame').value ) ; + else + SetAttribute( oLink, 'target', null ) ; + + // Advances Attributes + SetAttribute( oLink, 'id' , GetE('txtAttId').value ) ; + SetAttribute( oLink, 'name' , GetE('txtAttName').value ) ; // No IE. Set but doesnt't update the outerHTML. + SetAttribute( oLink, 'dir' , GetE('cmbAttLangDir').value ) ; + SetAttribute( oLink, 'lang' , GetE('txtAttLangCode').value ) ; + SetAttribute( oLink, 'accesskey', GetE('txtAttAccessKey').value ) ; + SetAttribute( oLink, 'tabindex' , ( GetE('txtAttTabIndex').value > 0 ? GetE('txtAttTabIndex').value : null ) ) ; + SetAttribute( oLink, 'title' , GetE('txtAttTitle').value ) ; + SetAttribute( oLink, 'type' , GetE('txtAttContentType').value ) ; + SetAttribute( oLink, 'charset' , GetE('txtAttCharSet').value ) ; + + if ( oEditor.FCKBrowserInfo.IsIE ) + { + SetAttribute( oLink, 'className', GetE('txtAttClasses').value ) ; + oLink.style.cssText = GetE('txtAttStyle').value ; + } + else + { + SetAttribute( oLink, 'class', GetE('txtAttClasses').value ) ; + SetAttribute( oLink, 'style', GetE('txtAttStyle').value ) ; + } + + return true ; +} + +function BrowseServer() +{ + OpenFileBrowser( FCKConfig.LinkBrowserURL, FCKConfig.LinkBrowserWindowWidth, FCKConfig.LinkBrowserWindowHeight ) ; +} + +function SetUrl( url ) +{ + document.getElementById('txtUrl').value = url ; + OnUrlChange() ; + window.parent.SetSelectedTab( 'Info' ) ; +} + +function OnUploadCompleted( errorNumber, fileUrl, fileName, customMsg ) +{ + switch ( errorNumber ) + { + case 0 : // No errors + alert( 'Your file has been successfully uploaded' ) ; + break ; + case 1 : // Custom error + alert( customMsg ) ; + return ; + case 101 : // Custom warning + alert( customMsg ) ; + break ; + case 201 : + alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ; + break ; + case 202 : + alert( 'Invalid file type' ) ; + return ; + case 203 : + alert( "Security error. You probably don't have enough permissions to upload. Please check your server." ) ; + return ; + default : + alert( 'Error on file upload. Error number: ' + errorNumber ) ; + return ; + } + + SetUrl( fileUrl ) ; + GetE('frmUpload').reset() ; +} + +var oUploadAllowedExtRegex = new RegExp( FCKConfig.LinkUploadAllowedExtensions, 'i' ) ; +var oUploadDeniedExtRegex = new RegExp( FCKConfig.LinkUploadDeniedExtensions, 'i' ) ; + +function CheckUpload() +{ + var sFile = GetE('txtUploadFile').value ; + + if ( sFile.length == 0 ) + { + alert( 'Please select a file to upload' ) ; + return false ; + } + + if ( ( FCKConfig.LinkUploadAllowedExtensions.length > 0 && !oUploadAllowedExtRegex.test( sFile ) ) || + ( FCKConfig.LinkUploadDeniedExtensions.length > 0 && oUploadDeniedExtRegex.test( sFile ) ) ) + { + OnUploadCompleted( 202 ) ; + return false ; + } + + return true ; +} \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_listprop.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_listprop.html new file mode 100644 index 00000000..b79f2f14 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_listprop.html @@ -0,0 +1,101 @@ + + + + + Bulleted List Properties + + + + + + + + + + +
+ + + + +
+ List Type
+ + +   +
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_paste.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_paste.html new file mode 100644 index 00000000..1f1dc4e2 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_paste.html @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + +
+ Please paste inside the following box using the + keyboard (Ctrl+V) and hit OK. +
+   +
+ + +
+ + + + + +
+ +
+ +
+ +
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_radiobutton.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_radiobutton.html new file mode 100644 index 00000000..97383f58 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_radiobutton.html @@ -0,0 +1,103 @@ + + + + + Radio Button Properties + + + + + + + + + + +
+ + + + + + + + + + +
+ Name
+ +
+ Value
+ +
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_replace.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_replace.html new file mode 100644 index 00000000..fda15a16 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_replace.html @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
  +
+   +
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_select.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_select.html new file mode 100644 index 00000000..b8f40410 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_select.html @@ -0,0 +1,172 @@ + + + + + Select Properties + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
Name 
Value 
Size  lines
+
+
+  Available + Options  + + + + + + + + + + + + + + + + + + +
Text
+ +
Value
+ +
+ + +
+
+ +
   +
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_select/fck_select.js b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_select/fck_select.js new file mode 100644 index 00000000..88e67a7d --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_select/fck_select.js @@ -0,0 +1,165 @@ +/* + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: fck_select.js + * Scripts for the fck_select.html page. + * + * File Authors: + * Frederico Caldeira Knabben (fredck@fckeditor.net) + */ + +function Select( combo ) +{ + var iIndex = combo.selectedIndex ; + + oListText.selectedIndex = iIndex ; + oListValue.selectedIndex = iIndex ; + + var oTxtText = document.getElementById( "txtText" ) ; + var oTxtValue = document.getElementById( "txtValue" ) ; + + oTxtText.value = oListText.value ; + oTxtValue.value = oListValue.value ; +} + +function Add() +{ + var oTxtText = document.getElementById( "txtText" ) ; + var oTxtValue = document.getElementById( "txtValue" ) ; + + AddComboOption( oListText, oTxtText.value, oTxtText.value ) ; + AddComboOption( oListValue, oTxtValue.value, oTxtValue.value ) ; + + oListText.selectedIndex = oListText.options.length - 1 ; + oListValue.selectedIndex = oListValue.options.length - 1 ; + + oTxtText.value = '' ; + oTxtValue.value = '' ; + + oTxtText.focus() ; +} + +function Modify() +{ + var iIndex = oListText.selectedIndex ; + + if ( iIndex < 0 ) return ; + + var oTxtText = document.getElementById( "txtText" ) ; + var oTxtValue = document.getElementById( "txtValue" ) ; + + oListText.options[ iIndex ].innerHTML = oTxtText.value ; + oListText.options[ iIndex ].value = oTxtText.value ; + + oListValue.options[ iIndex ].innerHTML = oTxtValue.value ; + oListValue.options[ iIndex ].value = oTxtValue.value ; + + oTxtText.value = '' ; + oTxtValue.value = '' ; + + oTxtText.focus() ; +} + +function Move( steps ) +{ + ChangeOptionPosition( oListText, steps ) ; + ChangeOptionPosition( oListValue, steps ) ; +} + +function Delete() +{ + RemoveSelectedOptions( oListText ) ; + RemoveSelectedOptions( oListValue ) ; +} + +function SetSelectedValue() +{ + var iIndex = oListValue.selectedIndex ; + if ( iIndex < 0 ) return ; + + var oTxtValue = document.getElementById( "txtSelValue" ) ; + + oTxtValue.value = oListValue.options[ iIndex ].value ; +} + +// Moves the selected option by a number of steps (also negative) +function ChangeOptionPosition( combo, steps ) +{ + var iActualIndex = combo.selectedIndex ; + + if ( iActualIndex < 0 ) + return ; + + var iFinalIndex = iActualIndex + steps ; + + if ( iFinalIndex < 0 ) + iFinalIndex = 0 ; + + if ( iFinalIndex > ( combo.options.lenght - 1 ) ) + iFinalIndex = combo.options.lenght - 1 ; + + if ( iActualIndex == iFinalIndex ) + return ; + + var oOption = combo.options[ iActualIndex ] ; + var sText = oOption.innerHTML ; + var sValue = oOption.value ; + + combo.remove( iActualIndex ) ; + + oOption = AddComboOption( combo, sText, sValue, null, iFinalIndex ) ; + + oOption.selected = true ; +} + +// Remove all selected options from a SELECT object +function RemoveSelectedOptions(combo) +{ + // Save the selected index + var iSelectedIndex = combo.selectedIndex ; + + var oOptions = combo.options ; + + // Remove all selected options + for ( var i = oOptions.length - 1 ; i >= 0 ; i-- ) + { + if (oOptions[i].selected) combo.remove(i) ; + } + + // Reset the selection based on the original selected index + if ( combo.options.length > 0 ) + { + if ( iSelectedIndex >= combo.options.length ) iSelectedIndex = combo.options.length - 1 ; + combo.selectedIndex = iSelectedIndex ; + } +} + +// Add a new option to a SELECT object (combo or list) +function AddComboOption( combo, optionText, optionValue, documentObject, index ) +{ + var oOption ; + + if ( documentObject ) + oOption = documentObject.createElement("OPTION") ; + else + oOption = document.createElement("OPTION") ; + + if ( index != null ) + combo.options.add( oOption, index ) ; + else + combo.options.add( oOption ) ; + + oOption.innerHTML = optionText.length > 0 ? optionText : ' ' ; + oOption.value = optionValue ; + + return oOption ; +} \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_smiley.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_smiley.html new file mode 100644 index 00000000..19737e7c --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_smiley.html @@ -0,0 +1,91 @@ + + + + + + + + + + + + +
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_source.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_source.html new file mode 100644 index 00000000..310ed34a --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_source.html @@ -0,0 +1,61 @@ + + + + + Source + + + + + + + + + + +
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_specialchar.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_specialchar.html new file mode 100644 index 00000000..3839181e --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_specialchar.html @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + +
+ + +
+
     + + + + +
 
+
+ + \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages.html new file mode 100644 index 00000000..526a8ff6 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages.html @@ -0,0 +1,59 @@ + + + + + Spell Check + + + + + + + + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/blank.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/blank.html new file mode 100644 index 00000000..e69de29b diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controlWindow.js b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controlWindow.js new file mode 100644 index 00000000..6ba8cf03 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controlWindow.js @@ -0,0 +1,87 @@ +//////////////////////////////////////////////////// +// controlWindow object +//////////////////////////////////////////////////// +function controlWindow( controlForm ) { + // private properties + this._form = controlForm; + + // public properties + this.windowType = "controlWindow"; +// this.noSuggestionSelection = "- No suggestions -"; // by FredCK + this.noSuggestionSelection = FCKLang.DlgSpellNoSuggestions ; + // set up the properties for elements of the given control form + this.suggestionList = this._form.sugg; + this.evaluatedText = this._form.misword; + this.replacementText = this._form.txtsugg; + this.undoButton = this._form.btnUndo; + + // public methods + this.addSuggestion = addSuggestion; + this.clearSuggestions = clearSuggestions; + this.selectDefaultSuggestion = selectDefaultSuggestion; + this.resetForm = resetForm; + this.setSuggestedText = setSuggestedText; + this.enableUndo = enableUndo; + this.disableUndo = disableUndo; +} + +function resetForm() { + if( this._form ) { + this._form.reset(); + } +} + +function setSuggestedText() { + var slct = this.suggestionList; + var txt = this.replacementText; + var str = ""; + if( (slct.options[0].text) && slct.options[0].text != this.noSuggestionSelection ) { + str = slct.options[slct.selectedIndex].text; + } + txt.value = str; +} + +function selectDefaultSuggestion() { + var slct = this.suggestionList; + var txt = this.replacementText; + if( slct.options.length == 0 ) { + this.addSuggestion( this.noSuggestionSelection ); + } else { + slct.options[0].selected = true; + } + this.setSuggestedText(); +} + +function addSuggestion( sugg_text ) { + var slct = this.suggestionList; + if( sugg_text ) { + var i = slct.options.length; + var newOption = new Option( sugg_text, 'sugg_text'+i ); + slct.options[i] = newOption; + } +} + +function clearSuggestions() { + var slct = this.suggestionList; + for( var j = slct.length - 1; j > -1; j-- ) { + if( slct.options[j] ) { + slct.options[j] = null; + } + } +} + +function enableUndo() { + if( this.undoButton ) { + if( this.undoButton.disabled == true ) { + this.undoButton.disabled = false; + } + } +} + +function disableUndo() { + if( this.undoButton ) { + if( this.undoButton.disabled == false ) { + this.undoButton.disabled = true; + } + } +} diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controls.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controls.html new file mode 100644 index 00000000..42d70414 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controls.html @@ -0,0 +1,153 @@ + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
Not in dictionary:
Change to:
+ + + + + + + +
+ +
+ +
+
   + + + + + + + + + + + + + + + + + + + + + + +
+ +    + +
+ +    + +
+ +    + +
+
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.cfm b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.cfm new file mode 100644 index 00000000..9564ed62 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.cfm @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php new file mode 100644 index 00000000..340ba9be --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php @@ -0,0 +1,193 @@ +$val ) { + # $val = str_replace( "'", "%27", $val ); + echo "textinputs[$key] = decodeURIComponent(\"" . $val . "\");\n"; + } +} + +# make declarations for the text input index +function print_textindex_decl( $text_input_idx ) { + echo "words[$text_input_idx] = [];\n"; + echo "suggs[$text_input_idx] = [];\n"; +} + +# set an element of the JavaScript 'words' array to a misspelled word +function print_words_elem( $word, $index, $text_input_idx ) { + echo "words[$text_input_idx][$index] = '" . escape_quote( $word ) . "';\n"; +} + + +# set an element of the JavaScript 'suggs' array to a list of suggestions +function print_suggs_elem( $suggs, $index, $text_input_idx ) { + echo "suggs[$text_input_idx][$index] = ["; + foreach( $suggs as $key=>$val ) { + if( $val ) { + echo "'" . escape_quote( $val ) . "'"; + if ( $key+1 < count( $suggs )) { + echo ", "; + } + } + } + echo "];\n"; +} + +# escape single quote +function escape_quote( $str ) { + return preg_replace ( "/'/", "\\'", $str ); +} + + +# handle a server-side error. +function error_handler( $err ) { + echo "error = '" . escape_quote( $err ) . "';\n"; +} + +## get the list of misspelled words. Put the results in the javascript words array +## for each misspelled word, get suggestions and put in the javascript suggs array +function print_checker_results() { + + global $aspell_prog; + global $aspell_opts; + global $tempfiledir; + global $textinputs; + global $input_separator; + $aspell_err = ""; + # create temp file + $tempfile = tempnam( $tempfiledir, 'aspell_data_' ); + + # open temp file, add the submitted text. + if( $fh = fopen( $tempfile, 'w' )) { + for( $i = 0; $i < count( $textinputs ); $i++ ) { + $text = urldecode( $textinputs[$i] ); + $lines = explode( "\n", $text ); + fwrite ( $fh, "%\n" ); # exit terse mode + fwrite ( $fh, "^$input_separator\n" ); + fwrite ( $fh, "!\n" ); # enter terse mode + foreach( $lines as $key=>$value ) { + # use carat on each line to escape possible aspell commands + fwrite( $fh, "^$value\n" ); + } + } + fclose( $fh ); + + # exec aspell command - redirect STDERR to STDOUT + $cmd = "$aspell_prog $aspell_opts < $tempfile 2>&1"; + if( $aspellret = shell_exec( $cmd )) { + $linesout = explode( "\n", $aspellret ); + $index = 0; + $text_input_index = -1; + # parse each line of aspell return + foreach( $linesout as $key=>$val ) { + $chardesc = substr( $val, 0, 1 ); + # if '&', then not in dictionary but has suggestions + # if '#', then not in dictionary and no suggestions + # if '*', then it is a delimiter between text inputs + # if '@' then version info + if( $chardesc == '&' || $chardesc == '#' ) { + $line = explode( " ", $val, 5 ); + print_words_elem( $line[1], $index, $text_input_index ); + if( isset( $line[4] )) { + $suggs = explode( ", ", $line[4] ); + } else { + $suggs = array(); + } + print_suggs_elem( $suggs, $index, $text_input_index ); + $index++; + } elseif( $chardesc == '*' ) { + $text_input_index++; + print_textindex_decl( $text_input_index ); + $index = 0; + } elseif( $chardesc != '@' && $chardesc != "" ) { + # assume this is error output + $aspell_err .= $val; + } + } + if( $aspell_err ) { + $aspell_err = "Error executing `$cmd`\\n$aspell_err"; + error_handler( $aspell_err ); + } + } else { + error_handler( "System error: Aspell program execution failed (`$cmd`)" ); + } + } else { + error_handler( "System error: Could not open file '$tempfile' for writing" ); + } + + # close temp file, delete file + unlink( $tempfile ); +} + + +?> + + + + + + + + + + + + + + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.pl b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.pl new file mode 100644 index 00000000..cf712005 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.pl @@ -0,0 +1,180 @@ +#!/usr/bin/perl + +use CGI qw/ :standard /; +use File::Temp qw/ tempfile tempdir /; + +# my $spellercss = '/speller/spellerStyle.css'; # by FredCK +my $spellercss = '../spellerStyle.css'; # by FredCK +# my $wordWindowSrc = '/speller/wordWindow.js'; # by FredCK +my $wordWindowSrc = '../wordWindow.js'; # by FredCK +my @textinputs = param( 'textinputs[]' ); # array +# my $aspell_cmd = 'aspell'; # by FredCK (for Linux) +my $aspell_cmd = '"C:\Program Files\Aspell\bin\aspell.exe"'; # by FredCK (for Windows) +my $lang = 'en_US'; +# my $aspell_opts = "-a --lang=$lang --encoding=utf-8"; # by FredCK +my $aspell_opts = "-a --lang=$lang --encoding=utf-8 -H"; # by FredCK +my $input_separator = "A"; + +# set the 'wordtext' JavaScript variable to the submitted text. +sub printTextVar { + for( my $i = 0; $i <= $#textinputs; $i++ ) { + print "textinputs[$i] = decodeURIComponent('" . escapeQuote( $textinputs[$i] ) . "')\n"; + } +} + +sub printTextIdxDecl { + my $idx = shift; + print "words[$idx] = [];\n"; + print "suggs[$idx] = [];\n"; +} + +sub printWordsElem { + my( $textIdx, $wordIdx, $word ) = @_; + print "words[$textIdx][$wordIdx] = '" . escapeQuote( $word ) . "';\n"; +} + +sub printSuggsElem { + my( $textIdx, $wordIdx, @suggs ) = @_; + print "suggs[$textIdx][$wordIdx] = ["; + for my $i ( 0..$#suggs ) { + print "'" . escapeQuote( $suggs[$i] ) . "'"; + if( $i < $#suggs ) { + print ", "; + } + } + print "];\n"; +} + +sub printCheckerResults { + my $textInputIdx = -1; + my $wordIdx = 0; + my $unhandledText; + # create temp file + my $dir = tempdir( CLEANUP => 1 ); + my( $fh, $tmpfilename ) = tempfile( DIR => $dir ); + + # temp file was created properly? + + # open temp file, add the submitted text. + for( my $i = 0; $i <= $#textinputs; $i++ ) { + $text = url_decode( $textinputs[$i] ); + @lines = split( /\n/, $text ); + print $fh "\%\n"; # exit terse mode + print $fh "^$input_separator\n"; + print $fh "!\n"; # enter terse mode + for my $line ( @lines ) { + # use carat on each line to escape possible aspell commands + print $fh "^$line\n"; + } + + } + # exec aspell command + my $cmd = "$aspell_cmd $aspell_opts < $tmpfilename 2>&1"; + open ASPELL, "$cmd |" or handleError( "Could not execute `$cmd`\\n$!" ) and return; + # parse each line of aspell return + for my $ret ( ) { + chomp( $ret ); + # if '&', then not in dictionary but has suggestions + # if '#', then not in dictionary and no suggestions + # if '*', then it is a delimiter between text inputs + if( $ret =~ /^\*/ ) { + $textInputIdx++; + printTextIdxDecl( $textInputIdx ); + $wordIdx = 0; + + } elsif( $ret =~ /^(&|#)/ ) { + my @tokens = split( " ", $ret, 5 ); + printWordsElem( $textInputIdx, $wordIdx, $tokens[1] ); + my @suggs = (); + if( $tokens[4] ) { + @suggs = split( ", ", $tokens[4] ); + } + printSuggsElem( $textInputIdx, $wordIdx, @suggs ); + $wordIdx++; + } else { + $unhandledText .= $ret; + } + } + close ASPELL or handleError( "Error executing `$cmd`\\n$unhandledText" ) and return; +} + +sub escapeQuote { + my $str = shift; + $str =~ s/'/\\'/g; + return $str; +} + +sub handleError { + my $err = shift; + print "error = '" . escapeQuote( $err ) . "';\n"; +} + +sub url_decode { + local $_ = @_ ? shift : $_; + defined or return; + # change + signs to spaces + tr/+/ /; + # change hex escapes to the proper characters + s/%([a-fA-F0-9]{2})/pack "H2", $1/eg; + return $_; +} + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Display HTML +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +print < + + + + + + + + + + + + + +EOF + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellChecker.js b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellChecker.js new file mode 100644 index 00000000..11c8d95d --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellChecker.js @@ -0,0 +1,458 @@ +//////////////////////////////////////////////////// +// spellChecker.js +// +// spellChecker object +// +// This file is sourced on web pages that have a textarea object to evaluate +// for spelling. It includes the implementation for the spellCheckObject. +// +//////////////////////////////////////////////////// + + +// constructor +function spellChecker( textObject ) { + + // public properties - configurable +// this.popUpUrl = '/speller/spellchecker.html'; // by FredCK + this.popUpUrl = 'fck_spellerpages/spellerpages/spellchecker.html'; // by FredCK + this.popUpName = 'spellchecker'; +// this.popUpProps = "menu=no,width=440,height=350,top=70,left=120,resizable=yes,status=yes"; // by FredCK + this.popUpProps = null ; // by FredCK +// this.spellCheckScript = '/speller/server-scripts/spellchecker.php'; // by FredCK + this.spellCheckScript = 'server-scripts/spellchecker.php'; // by FredCK + //this.spellCheckScript = '/cgi-bin/spellchecker.pl'; + + // values used to keep track of what happened to a word + this.replWordFlag = "R"; // single replace + this.ignrWordFlag = "I"; // single ignore + this.replAllFlag = "RA"; // replace all occurances + this.ignrAllFlag = "IA"; // ignore all occurances + this.fromReplAll = "~RA"; // an occurance of a "replace all" word + this.fromIgnrAll = "~IA"; // an occurance of a "ignore all" word + // properties set at run time + this.wordFlags = new Array(); + this.currentTextIndex = 0; + this.currentWordIndex = 0; + this.spellCheckerWin = null; + this.controlWin = null; + this.wordWin = null; + this.textArea = textObject; // deprecated + this.textInputs = arguments; + + // private methods + this._spellcheck = _spellcheck; + this._getSuggestions = _getSuggestions; + this._setAsIgnored = _setAsIgnored; + this._getTotalReplaced = _getTotalReplaced; + this._setWordText = _setWordText; + this._getFormInputs = _getFormInputs; + + // public methods + this.openChecker = openChecker; + this.startCheck = startCheck; + this.checkTextBoxes = checkTextBoxes; + this.checkTextAreas = checkTextAreas; + this.spellCheckAll = spellCheckAll; + this.ignoreWord = ignoreWord; + this.ignoreAll = ignoreAll; + this.replaceWord = replaceWord; + this.replaceAll = replaceAll; + this.terminateSpell = terminateSpell; + this.undo = undo; + + // set the current window's "speller" property to the instance of this class. + // this object can now be referenced by child windows/frames. + window.speller = this; +} + +// call this method to check all text boxes (and only text boxes) in the HTML document +function checkTextBoxes() { + this.textInputs = this._getFormInputs( "^text$" ); + this.openChecker(); +} + +// call this method to check all textareas (and only textareas ) in the HTML document +function checkTextAreas() { + this.textInputs = this._getFormInputs( "^textarea$" ); + this.openChecker(); +} + +// call this method to check all text boxes and textareas in the HTML document +function spellCheckAll() { + this.textInputs = this._getFormInputs( "^text(area)?$" ); + this.openChecker(); +} + +// call this method to check text boxe(s) and/or textarea(s) that were passed in to the +// object's constructor or to the textInputs property +function openChecker() { + this.spellCheckerWin = window.open( this.popUpUrl, this.popUpName, this.popUpProps ); + if( !this.spellCheckerWin.opener ) { + this.spellCheckerWin.opener = window; + } +} + +function startCheck( wordWindowObj, controlWindowObj ) { + + // set properties from args + this.wordWin = wordWindowObj; + this.controlWin = controlWindowObj; + + // reset properties + this.wordWin.resetForm(); + this.controlWin.resetForm(); + this.currentTextIndex = 0; + this.currentWordIndex = 0; + // initialize the flags to an array - one element for each text input + this.wordFlags = new Array( this.wordWin.textInputs.length ); + // each element will be an array that keeps track of each word in the text + for( var i=0; i wi ) || i > ti ) { + // future word: set as "from ignore all" if + // 1) do not already have a flag and + // 2) have the same value as current word + if(( this.wordWin.getTextVal( i, j ) == s_word_to_repl ) + && ( !this.wordFlags[i][j] )) { + this._setAsIgnored( i, j, this.fromIgnrAll ); + } + } + } + } + + // finally, move on + this.currentWordIndex++; + this._spellcheck(); +} + +function replaceWord() { + var wi = this.currentWordIndex; + var ti = this.currentTextIndex; + if( !this.wordWin ) { + alert( 'Error: Word frame not available.' ); + return false; + } + if( !this.wordWin.getTextVal( ti, wi )) { + alert( 'Error: "Not in dictionary" text is missing' ); + return false; + } + if( !this.controlWin.replacementText ) { + return; + } + var txt = this.controlWin.replacementText; + if( txt.value ) { + var newspell = new String( txt.value ); + if( this._setWordText( ti, wi, newspell, this.replWordFlag )) { + this.currentWordIndex++; + this._spellcheck(); + } + } +} + +function replaceAll() { + var ti = this.currentTextIndex; + var wi = this.currentWordIndex; + if( !this.wordWin ) { + alert( 'Error: Word frame not available.' ); + return false; + } + var s_word_to_repl = this.wordWin.getTextVal( ti, wi ); + if( !s_word_to_repl ) { + alert( 'Error: "Not in dictionary" text is missing' ); + return false; + } + var txt = this.controlWin.replacementText; + if( !txt.value ) return; + var newspell = new String( txt.value ); + + // set this word as a "replace all" word. + this._setWordText( ti, wi, newspell, this.replAllFlag ); + + // loop through all the words after this word + for( var i = ti; i < this.wordWin.textInputs.length; i++ ) { + for( var j = 0; j < this.wordWin.totalWords( i ); j++ ) { + if(( i == ti && j > wi ) || i > ti ) { + // future word: set word text to s_word_to_repl if + // 1) do not already have a flag and + // 2) have the same value as s_word_to_repl + if(( this.wordWin.getTextVal( i, j ) == s_word_to_repl ) + && ( !this.wordFlags[i][j] )) { + this._setWordText( i, j, newspell, this.fromReplAll ); + } + } + } + } + + // finally, move on + this.currentWordIndex++; + this._spellcheck(); +} + +function terminateSpell() { + // called when we have reached the end of the spell checking. + var msg = ""; // by FredCK + var numrepl = this._getTotalReplaced(); + if( numrepl == 0 ) { + // see if there were no misspellings to begin with + if( !this.wordWin ) { + msg = ""; + } else { + if( this.wordWin.totalMisspellings() ) { +// msg += "No words changed."; // by FredCK + msg += FCKLang.DlgSpellNoChanges ; // by FredCK + } else { +// msg += "No misspellings found."; // by FredCK + msg += FCKLang.DlgSpellNoMispell ; // by FredCK + } + } + } else if( numrepl == 1 ) { +// msg += "One word changed."; // by FredCK + msg += FCKLang.DlgSpellOneChange ; // by FredCK + } else { +// msg += numrepl + " words changed."; // by FredCK + msg += FCKLang.DlgSpellManyChanges.replace( /%1/g, numrepl ) ; + } + if( msg ) { +// msg += "\n"; // by FredCK + alert( msg ); + } + + if( numrepl > 0 ) { + // update the text field(s) on the opener window + for( var i = 0; i < this.textInputs.length; i++ ) { + // this.textArea.value = this.wordWin.text; + if( this.wordWin ) { + if( this.wordWin.textInputs[i] ) { + this.textInputs[i].value = this.wordWin.textInputs[i]; + } + } + } + } + + // return back to the calling window +// this.spellCheckerWin.close(); // by FredCK + if ( typeof( this.OnFinished ) == 'function' ) // by FredCK + this.OnFinished(numrepl) ; // by FredCK + + return true; +} + +function undo() { + // skip if this is the first word! + var ti = this.currentTextIndex; + var wi = this.currentWordIndex + + if( this.wordWin.totalPreviousWords( ti, wi ) > 0 ) { + this.wordWin.removeFocus( ti, wi ); + + // go back to the last word index that was acted upon + do { + // if the current word index is zero then reset the seed + if( this.currentWordIndex == 0 && this.currentTextIndex > 0 ) { + this.currentTextIndex--; + this.currentWordIndex = this.wordWin.totalWords( this.currentTextIndex )-1; + if( this.currentWordIndex < 0 ) this.currentWordIndex = 0; + } else { + if( this.currentWordIndex > 0 ) { + this.currentWordIndex--; + } + } + } while ( + this.wordWin.totalWords( this.currentTextIndex ) == 0 + || this.wordFlags[this.currentTextIndex][this.currentWordIndex] == this.fromIgnrAll + || this.wordFlags[this.currentTextIndex][this.currentWordIndex] == this.fromReplAll + ); + + var text_idx = this.currentTextIndex; + var idx = this.currentWordIndex; + var preReplSpell = this.wordWin.originalSpellings[text_idx][idx]; + + // if we got back to the first word then set the Undo button back to disabled + if( this.wordWin.totalPreviousWords( text_idx, idx ) == 0 ) { + this.controlWin.disableUndo(); + } + + // examine what happened to this current word. + switch( this.wordFlags[text_idx][idx] ) { + // replace all: go through this and all the future occurances of the word + // and revert them all to the original spelling and clear their flags + case this.replAllFlag : + for( var i = text_idx; i < this.wordWin.textInputs.length; i++ ) { + for( var j = 0; j < this.wordWin.totalWords( i ); j++ ) { + if(( i == text_idx && j >= idx ) || i > text_idx ) { + var origSpell = this.wordWin.originalSpellings[i][j]; + if( origSpell == preReplSpell ) { + this._setWordText ( i, j, origSpell, undefined ); + } + } + } + } + break; + + // ignore all: go through all the future occurances of the word + // and clear their flags + case this.ignrAllFlag : + for( var i = text_idx; i < this.wordWin.textInputs.length; i++ ) { + for( var j = 0; j < this.wordWin.totalWords( i ); j++ ) { + if(( i == text_idx && j >= idx ) || i > text_idx ) { + var origSpell = this.wordWin.originalSpellings[i][j]; + if( origSpell == preReplSpell ) { + this.wordFlags[i][j] = undefined; + } + } + } + } + break; + + // replace: revert the word to its original spelling + case this.replWordFlag : + this._setWordText ( text_idx, idx, preReplSpell, undefined ); + break; + } + + // For all four cases, clear the wordFlag of this word. re-start the process + this.wordFlags[text_idx][idx] = undefined; + this._spellcheck(); + } +} + +function _spellcheck() { + var ww = this.wordWin; + + // check if this is the last word in the current text element + if( this.currentWordIndex == ww.totalWords( this.currentTextIndex) ) { + this.currentTextIndex++; + this.currentWordIndex = 0; + // keep going if we're not yet past the last text element + if( this.currentTextIndex < this.wordWin.textInputs.length ) { + this._spellcheck(); + return; + } else { + this.terminateSpell(); + return; + } + } + + // if this is after the first one make sure the Undo button is enabled + if( this.currentWordIndex > 0 ) { + this.controlWin.enableUndo(); + } + + // skip the current word if it has already been worked on + if( this.wordFlags[this.currentTextIndex][this.currentWordIndex] ) { + // increment the global current word index and move on. + this.currentWordIndex++; + this._spellcheck(); + } else { + var evalText = ww.getTextVal( this.currentTextIndex, this.currentWordIndex ); + if( evalText ) { + this.controlWin.evaluatedText.value = evalText; + ww.setFocus( this.currentTextIndex, this.currentWordIndex ); + this._getSuggestions( this.currentTextIndex, this.currentWordIndex ); + } + } +} + +function _getSuggestions( text_num, word_num ) { + this.controlWin.clearSuggestions(); + // add suggestion in list for each suggested word. + // get the array of suggested words out of the + // three-dimensional array containing all suggestions. + var a_suggests = this.wordWin.suggestions[text_num][word_num]; + if( a_suggests ) { + // got an array of suggestions. + for( var ii = 0; ii < a_suggests.length; ii++ ) { + this.controlWin.addSuggestion( a_suggests[ii] ); + } + } + this.controlWin.selectDefaultSuggestion(); +} + +function _setAsIgnored( text_num, word_num, flag ) { + // set the UI + this.wordWin.removeFocus( text_num, word_num ); + // do the bookkeeping + this.wordFlags[text_num][word_num] = flag; + return true; +} + +function _getTotalReplaced() { + var i_replaced = 0; + for( var i = 0; i < this.wordFlags.length; i++ ) { + for( var j = 0; j < this.wordFlags[i].length; j++ ) { + if(( this.wordFlags[i][j] == this.replWordFlag ) + || ( this.wordFlags[i][j] == this.replAllFlag ) + || ( this.wordFlags[i][j] == this.fromReplAll )) { + i_replaced++; + } + } + } + return i_replaced; +} + +function _setWordText( text_num, word_num, newText, flag ) { + // set the UI and form inputs + this.wordWin.setText( text_num, word_num, newText ); + // keep track of what happened to this word: + this.wordFlags[text_num][word_num] = flag; + return true; +} + +function _getFormInputs( inputPattern ) { + var inputs = new Array(); + for( var i = 0; i < document.forms.length; i++ ) { + for( var j = 0; j < document.forms[i].elements.length; j++ ) { + if( document.forms[i].elements[j].type.match( inputPattern )) { + inputs[inputs.length] = document.forms[i].elements[j]; + } + } + } + return inputs; +} + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellchecker.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellchecker.html new file mode 100644 index 00000000..c419d23d --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellchecker.html @@ -0,0 +1,71 @@ + + + + + + +Speller Pages + + + + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellerStyle.css b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellerStyle.css new file mode 100644 index 00000000..47bc1efb --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellerStyle.css @@ -0,0 +1,49 @@ +.blend { + font-family: courier new; + font-size: 10pt; + border: 0; + margin-bottom:-1; +} +.normalLabel { + font-size:8pt; +} +.normalText { + font-family:arial, helvetica, sans-serif; + font-size:10pt; + color:000000; + background-color:FFFFFF; +} +.plainText { + font-family: courier new, courier, monospace; + font-size: 10pt; + color:000000; + background-color:FFFFFF; +} +.controlWindowBody { + font-family:arial, helvetica, sans-serif; + font-size:8pt; + padding: 7px ; /* by FredCK */ + margin: 0px ; /* by FredCK */ + /* color:000000; by FredCK */ + /* background-color:DADADA; by FredCK */ +} +.readonlyInput { + background-color:DADADA; + color:000000; + font-size:8pt; + width:392px; +} +.textDefault { + font-size:8pt; + width: 200px; +} +.buttonDefault { + width:90px; + height:22px; + font-size:8pt; +} +.suggSlct { + width:200px; + margin-top:2; + font-size:8pt; +} \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/wordWindow.js b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/wordWindow.js new file mode 100644 index 00000000..a4d464b1 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/wordWindow.js @@ -0,0 +1,271 @@ +//////////////////////////////////////////////////// +// wordWindow object +//////////////////////////////////////////////////// +function wordWindow() { + // private properties + this._forms = []; + + // private methods + this._getWordObject = _getWordObject; + //this._getSpellerObject = _getSpellerObject; + this._wordInputStr = _wordInputStr; + this._adjustIndexes = _adjustIndexes; + this._isWordChar = _isWordChar; + this._lastPos = _lastPos; + + // public properties + this.wordChar = /[a-zA-Z]/; + this.windowType = "wordWindow"; + this.originalSpellings = new Array(); + this.suggestions = new Array(); + this.checkWordBgColor = "pink"; + this.normWordBgColor = "white"; + this.text = ""; + this.textInputs = new Array(); + this.indexes = new Array(); + //this.speller = this._getSpellerObject(); + + // public methods + this.resetForm = resetForm; + this.totalMisspellings = totalMisspellings; + this.totalWords = totalWords; + this.totalPreviousWords = totalPreviousWords; + //this.getTextObjectArray = getTextObjectArray; + this.getTextVal = getTextVal; + this.setFocus = setFocus; + this.removeFocus = removeFocus; + this.setText = setText; + //this.getTotalWords = getTotalWords; + this.writeBody = writeBody; + this.printForHtml = printForHtml; +} + +function resetForm() { + if( this._forms ) { + for( var i = 0; i < this._forms.length; i++ ) { + this._forms[i].reset(); + } + } + return true; +} + +function totalMisspellings() { + var total_words = 0; + for( var i = 0; i < this.textInputs.length; i++ ) { + total_words += this.totalWords( i ); + } + return total_words; +} + +function totalWords( textIndex ) { + return this.originalSpellings[textIndex].length; +} + +function totalPreviousWords( textIndex, wordIndex ) { + var total_words = 0; + for( var i = 0; i <= textIndex; i++ ) { + for( var j = 0; j < this.totalWords( i ); j++ ) { + if( i == textIndex && j == wordIndex ) { + break; + } else { + total_words++; + } + } + } + return total_words; +} + +//function getTextObjectArray() { +// return this._form.elements; +//} + +function getTextVal( textIndex, wordIndex ) { + var word = this._getWordObject( textIndex, wordIndex ); + if( word ) { + return word.value; + } +} + +function setFocus( textIndex, wordIndex ) { + var word = this._getWordObject( textIndex, wordIndex ); + if( word ) { + if( word.type == "text" ) { + word.focus(); + word.style.backgroundColor = this.checkWordBgColor; + } + } +} + +function removeFocus( textIndex, wordIndex ) { + var word = this._getWordObject( textIndex, wordIndex ); + if( word ) { + if( word.type == "text" ) { + word.blur(); + word.style.backgroundColor = this.normWordBgColor; + } + } +} + +function setText( textIndex, wordIndex, newText ) { + var word = this._getWordObject( textIndex, wordIndex ); + var beginStr; + var endStr; + if( word ) { + var pos = this.indexes[textIndex][wordIndex]; + var oldText = word.value; + // update the text given the index of the string + beginStr = this.textInputs[textIndex].substring( 0, pos ); + endStr = this.textInputs[textIndex].substring( + pos + oldText.length, + this.textInputs[textIndex].length + ); + this.textInputs[textIndex] = beginStr + newText + endStr; + + // adjust the indexes on the stack given the differences in + // length between the new word and old word. + var lengthDiff = newText.length - oldText.length; + this._adjustIndexes( textIndex, wordIndex, lengthDiff ); + + word.size = newText.length; + word.value = newText; + this.removeFocus( textIndex, wordIndex ); + } +} + + +function writeBody() { + var d = window.document; + var is_html = false; + + d.open(); + + // iterate through each text input. + for( var txtid = 0; txtid < this.textInputs.length; txtid++ ) { + var end_idx = 0; + var begin_idx = 0; + d.writeln( '
' ); + var wordtxt = this.textInputs[txtid]; + this.indexes[txtid] = []; + + if( wordtxt ) { + var orig = this.originalSpellings[txtid]; + if( !orig ) break; + + //!!! plain text, or HTML mode? + d.writeln( '
' ); + // iterate through each occurrence of a misspelled word. + for( var i = 0; i < orig.length; i++ ) { + // find the position of the current misspelled word, + // starting at the last misspelled word. + // and keep looking if it's a substring of another word + do { + begin_idx = wordtxt.indexOf( orig[i], end_idx ); + end_idx = begin_idx + orig[i].length; + // word not found? messed up! + if( begin_idx == -1 ) break; + // look at the characters immediately before and after + // the word. If they are word characters we'll keep looking. + var before_char = wordtxt.charAt( begin_idx - 1 ); + var after_char = wordtxt.charAt( end_idx ); + } while ( + this._isWordChar( before_char ) + || this._isWordChar( after_char ) + ); + + // keep track of its position in the original text. + this.indexes[txtid][i] = begin_idx; + + // write out the characters before the current misspelled word + for( var j = this._lastPos( txtid, i ); j < begin_idx; j++ ) { + // !!! html mode? make it html compatible + d.write( this.printForHtml( wordtxt.charAt( j ))); + } + + // write out the misspelled word. + d.write( this._wordInputStr( orig[i] )); + + // if it's the last word, write out the rest of the text + if( i == orig.length-1 ){ + d.write( printForHtml( wordtxt.substr( end_idx ))); + } + } + + d.writeln( '
' ); + + } + d.writeln( '
' ); + } + //for ( var j = 0; j < d.forms.length; j++ ) { + // alert( d.forms[j].name ); + // for( var k = 0; k < d.forms[j].elements.length; k++ ) { + // alert( d.forms[j].elements[k].name + ": " + d.forms[j].elements[k].value ); + // } + //} + + // set the _forms property + this._forms = d.forms; + d.close(); +} + +// return the character index in the full text after the last word we evaluated +function _lastPos( txtid, idx ) { + if( idx > 0 ) + return this.indexes[txtid][idx-1] + this.originalSpellings[txtid][idx-1].length; + else + return 0; +} + +function printForHtml( n ) { + return n ; // by FredCK + + var htmlstr = n; + if( htmlstr.length == 1 ) { + // do simple case statement if it's just one character + switch ( n ) { + case "\n": + htmlstr = '
'; + break; + case "<": + htmlstr = '<'; + break; + case ">": + htmlstr = '>'; + break; + } + return htmlstr; + } else { + htmlstr = htmlstr.replace( //g, '>' ); + htmlstr = htmlstr.replace( /\n/g, '
' ); + return htmlstr; + } +} + +function _isWordChar( letter ) { + if( letter.search( this.wordChar ) == -1 ) { + return false; + } else { + return true; + } +} + +function _getWordObject( textIndex, wordIndex ) { + if( this._forms[textIndex] ) { + if( this._forms[textIndex].elements[wordIndex] ) { + return this._forms[textIndex].elements[wordIndex]; + } + } + return null; +} + +function _wordInputStr( word ) { + var str = ''; + return str; +} + +function _adjustIndexes( textIndex, wordIndex, lengthDiff ) { + for( var i = wordIndex + 1; i < this.originalSpellings[textIndex].length; i++ ) { + this.indexes[textIndex][i] = this.indexes[textIndex][i] + lengthDiff; + } +} diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_table.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_table.html new file mode 100644 index 00000000..1d13d40a --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_table.html @@ -0,0 +1,282 @@ + + + + + Table Properties + + + + + + + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
Rows: 
Columns: 
  
Border size: 
Alignment: 
+
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
Width:  
Height:  pixels
   
Cell spacing:  
Cell padding:  
+
+ + + + + + + + + + + + +
Caption:   +
Summary:   +
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_tablecell.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_tablecell.html new file mode 100644 index 00000000..53984adc --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_tablecell.html @@ -0,0 +1,217 @@ + + + + + Table Cell Properties + + + + + + + + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Width:  
Height:  pixels
  
Word Wrap: 
  
Horizontal Alignment: 
Vertival Alignement: 
+
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rows Span: 
Columns Span: 
   
Background Color:  
Border Color:  
+
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_template.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_template.html new file mode 100644 index 00000000..c293e463 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_template.html @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + +
+ Please select the template to open in the editor
+ (the actual contents will be lost):
+
+
+ + +
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_textarea.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_textarea.html new file mode 100644 index 00000000..b42b9f75 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_textarea.html @@ -0,0 +1,90 @@ + + + + + Text Area Properties + + + + + + + + + + +
+ + + + +
+ Name
+ + Collumns
+ +
+ Rows
+ +
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_textfield.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_textfield.html new file mode 100644 index 00000000..6cc18f6b --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_textfield.html @@ -0,0 +1,131 @@ + + + + + Text Field Properties + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ Name
+ +
+ Value
+ +
+ Character Width
+ +
+ Maximum Characters
+ +
+ Type
+ +
 
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey.html b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey.html new file mode 100644 index 00000000..0e95a70d --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey.html @@ -0,0 +1,63 @@ + + + + + Universal Keyboard + + + + + + + + + + + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/00.gif b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/00.gif new file mode 100644 index 0000000000000000000000000000000000000000..fc2560981ee1caca400e225e48d282106f907f2d GIT binary patch literal 43 ucmZ?wbhEHbWMp7uXkcLY|NlP&1B2pE7Df>utpmhBaYhCPCMFj~25SJyItL8^ literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/data.js b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/data.js new file mode 100644 index 00000000..0712ffe2 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/data.js @@ -0,0 +1,70 @@ +/* + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: data.js + * Scripts for the fck_universalkey.html page. + * Definition des 104 caracteres en hexa unicode. + * + * File Authors: + * Michel Staelens (michel.staelens@wanadoo.fr) + * Abdul-Aziz Al-Oraij (top7up@hotmail.com) + */ + +var Maj = new Array() ; +var Min = new Array() ; + +Maj["Arabic"] ="0651|0021|0040|0023|0024|0025|005E|0026|002A|0029|0028|005F|002B|064E|064B|064F|064C|0625|0625|2018|00F7|00D7|061B|003C|003E|0650|064D|005D|005B|0623|0623|0640|060C|002F|003A|0022|007E|0652|007D|007B|0622|0622|2019|002C|002E|061F|007C|0020|0020|0020|0020|0020" ; +Min["Arabic"] ="0630|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|002D|003D|0636|0635|062B|0642|0641|063A|0639|0647|062E|062D|062C|062F|0634|0633|064A|0628|0644|0627|062A|0646|0645|0643|0637|0626|0621|0624|0631|0644|0627|0649|0629|0648|0632|0638|005C|0020|0020|0020|0020" ; +Maj["Belarusian (C)"] ="0401|0021|0022|2116|003B|0025|003A|003F|002A|0028|0029|005F|002B|0419|0426|0423|041A|0415|041D|0413|0428|040E|0417|0425|0027|0424|042B|0412|0410|041F|0420|041E|041B|0414|0416|042D|042F|0427|0421|041C|0406|0422|042C|0411|042E|002C|0020|0020|0020|0020|0020|0020" ; +Min["Belarusian (C)"] ="0451|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|002D|003D|0439|0446|0443|043A|0435|043D|0433|0448|045E|0437|0445|0027|0444|044B|0432|0430|043F|0440|043E|043B|0434|0436|044D|044F|0447|0441|043C|0456|0442|044C|0431|044E|002E|0020|0020|0020|0020|0020|0020" ; +Maj["Bulgarian (C)"] ="007E|0021|003F|002B|0022|0025|003D|003A|002F|005F|2116|0406|0056|044B|0423|0415|0418|0428|0429|041A|0421|0414|0417|0426|00A7|042C|042F|0410|041E|0416|0413|0422|041D|0412|041C|0427|042E|0419|042A|042D|0424|0425|041F|0420|041B|0411|0029|0020|0020|0020|0020|0020" ; +Min["Bulgarian (C)"] ="0060|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|002D|002E|002C|0443|0435|0438|0448|0449|043A|0441|0434|0437|0446|003B|044C|044F|0430|043E|0436|0433|0442|043D|0432|043C|0447|044E|0439|044A|044D|0444|0445|043F|0440|043B|0431|0028|0020|0020|0020|0020|0020" ; +Maj["Croatian (L)"] ="00B8|0021|0022|0023|0024|0025|0026|002F|0028|0029|003D|003F|00A8|0051|0057|0045|0052|0054|005A|0055|0049|004F|0050|0160|0110|0041|0053|0044|0046|0047|0048|004A|004B|004C|010C|0106|0059|0058|0043|0056|0042|004E|004D|017D|003B|003A|003C|003E|005F|002D|002A|002B" ; +Min["Croatian (L)"] ="00B8|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|0027|00A8|0071|0077|0065|0072|0074|007A|0075|0069|006F|0070|0161|0111|0061|0073|0064|0066|0067|0068|006A|006B|006C|010D|0107|0079|0078|0063|0076|0062|006E|006D|017E|002C|002E|003C|003E|005F|002D|002A|002B" ; +Maj["Czech (L)"] ="00B0|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|0025|02C7|0051|0057|0045|0052|0054|005A|0055|0049|004F|0050|002F|0028|0041|0053|0044|0046|0047|0048|004A|004B|004C|0022|0027|0059|0058|0043|0056|0042|004E|004D|003F|003A|005F|005B|007B|0021|0020|0148|010F" ; +Min["Czech (L)"] ="003B|002B|011B|0161|010D|0159|017E|00FD|00E1|00ED|00E9|003D|00B4|0071|0077|0065|0072|0074|007A|0075|0069|006F|0070|00FA|0029|0061|0073|0064|0066|0067|0068|006A|006B|006C|016F|00A7|0079|0078|0063|0076|0062|006E|006D|002C|002E|002D|005D|007D|00A8|0040|00F3|0165" ; +Maj["Danish (L)"] ="00A7|0021|0022|0023|00A4|0025|0026|002F|0028|0029|003D|003F|0060|0051|0057|0045|0052|0054|0059|0055|0049|004F|0050|00C5|005E|0041|0053|0044|0046|0047|0048|004A|004B|004C|00C6|00D8|003E|005A|0058|0043|0056|0042|004E|004D|003B|003A|002A|005F|007B|007D|005C|007E" ; +Min["Danish (L)"] ="00BD|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|002B|00B4|0071|0077|0065|0072|0074|0079|0075|0069|006F|0070|00E5|00A8|0061|0073|0064|0066|0067|0068|006A|006B|006C|00E6|00F8|003C|007A|0078|0063|0076|0062|006E|006D|002C|002E|0027|002D|005B|005D|007C|0040" ; +Maj["Farsi"] ="0020|0021|0040|0023|0024|0025|005E|0026|002A|0029|0028|005F|002B|0020|0020|0020|0020|0020|0020|0020|00F7|00D7|0020|007D|007B|0020|0020|005D|005B|0623|0622|0640|060C|061B|003A|0022|007E|0020|0020|0020|0020|0020|2019|003E|003C|061F|007C|0020|0020|0020|0020|0020" +Min["Farsi"] ="067E|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|002D|003D|0636|0635|062B|0642|0641|063A|0639|0647|062E|062D|062C|0686|0634|0633|064A|0628|0644|0627|062A|0646|0645|0643|06AF|0638|0637|0632|0631|0630|062F|0621|0648|002E|002F|005C|0020|0020|0020|0020|0020" +Maj["Finnish (L)"] ="00A7|0021|0022|0023|00A4|0025|0026|002F|0028|0029|003D|003F|0060|0051|0057|0045|0052|0054|0059|0055|0049|004F|0050|00C5|005E|0041|0053|0044|0046|0047|0048|004A|004B|004C|00D6|00C4|003E|005A|0058|0043|0056|0042|004E|004D|003B|003A|002A|005F|007B|007D|005C|007E" ; +Min["Finnish (L)"] ="00BD|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|002B|00B4|0071|0077|0065|0072|0074|0079|0075|0069|006F|0070|00E5|00A8|0061|0073|0064|0066|0067|0068|006A|006B|006C|00F6|00E4|003C|007A|0078|0063|0076|0062|006E|006D|002C|002E|0027|002D|005B|005D|007C|0040" ; +Maj["French (L)"] ="0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|00B0|002B|0023|0041|005A|0045|0052|0054|0059|0055|0049|004F|0050|00A8|0025|0051|0053|0044|0046|0047|0048|004A|004B|004C|004D|00B5|0057|0058|0043|0056|0042|004E|003F|002E|002F|00A7|003C|005B|007B|00A3|007E|0020" ; +Min["French (L)"] ="0026|00E9|0022|0027|0028|002D|00E8|005F|00E7|00E0|0029|003D|0040|0061|007A|0065|0072|0074|0079|0075|0069|006F|0070|005E|00F9|0071|0073|0064|0066|0067|0068|006A|006B|006C|006D|002A|0077|0078|0063|0076|0062|006E|002C|003B|003A|0021|003E|005D|007D|0024|007E|0020" ; +Maj["Greek"] ="007E|0021|0040|0023|0024|0025|0390|0026|03B0|0028|0029|005F|002B|003A|03A3|0395|03A1|03A4|03A5|0398|0399|039F|03A0|0386|038F|0391|03A3|0394|03A6|0393|0397|039E|039A|039B|038C|0022|0396|03A7|03A8|03A9|0392|039D|039C|003C|003E|003F|0388|0389|038A|03AA|03AB|038E" ; +Min["Greek"] ="0060|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|002D|003D|003B|03C2|03B5|03C1|03C4|03C5|03B8|03B9|03BF|03C0|03AC|03CE|03B1|03C3|03B4|03C6|03B3|03B7|03BE|03BA|03BB|03CC|0027|03B6|03C7|03C8|03C9|03B2|03BD|03BC|002C|002E|002F|03AD|03AE|03AF|03CA|03CB|03CD" ; +Maj["Hebrew"] ="007E|0021|0040|0023|0024|0025|005E|0026|002A|0028|0029|005F|002B|0051|0057|0045|0052|0054|0059|0055|0049|004F|0050|007B|007D|0041|0053|0044|0046|0047|0048|004A|004B|004C|003A|0022|005A|0058|0043|0056|0042|004E|004D|003C|003E|003F|0020|0020|0020|0020|0020|0020" ; +Min["Hebrew"] ="0060|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|002D|003D|002F|0027|05E7|05E8|05D0|05D8|05D5|05DF|05DD|05E4|005B|005D|05E9|05D3|05D2|05DB|05E2|05D9|05D7|05DC|05DA|05E3|002C|05D6|05E1|05D1|05D4|05E0|05DE|05E6|05EA|05E5|002E|0020|0020|0020|0020|0020|0020" ; +Maj["Hungarian (L)"] ="00A7|0027|0022|002B|0021|0025|002F|003D|0028|0029|00ED|00DC|00D3|0051|0057|0045|0052|0054|005A|0055|0049|004F|0050|0150|00DA|0041|0053|0044|0046|0047|0048|004A|004B|004C|00C9|00C1|0170|00CD|0059|0058|0043|0056|0042|004E|004D|003F|002E|003A|002D|005F|007B|007D" ; +Min["Hungarian (L)"] ="0030|0031|0032|0033|0034|0035|0036|0037|0038|0039|00F6|00FC|00F3|0071|0077|0065|0072|0074|007A|0075|0069|006F|0070|0151|00FA|0061|0073|0064|0066|0067|0068|006A|006B|006C|00E9|00E1|0171|00ED|0079|0078|0063|0076|0062|006E|006D|002C|002E|003A|002D|005F|007B|007D" ; +Maj["Diacritical (L)"] ="0060|00B4|005E|00A8|007E|00B0|00B7|00B8|00AF|02D9|02DB|02C7|02D8|0051|0057|0045|0052|0054|005A|0055|0049|004F|0050|00C6|02DD|0041|0053|0044|0046|0047|0048|004A|004B|004C|0141|0152|0059|0058|0043|0056|0042|004E|004D|01A0|01AF|00D8|0126|0110|0132|00DE|00D0|00DF" ; +Min["Diacritical (L)"] ="0060|00B4|005E|00A8|007E|00B0|00B7|00B8|00AF|02D9|02DB|02C7|02D8|0071|0077|0065|0072|0074|007A|0075|0069|006F|0070|00E6|02DD|0061|0073|0064|0066|0067|0068|006A|006B|006C|0142|0153|0079|0078|0063|0076|0062|006E|006D|01A1|01B0|00F8|0127|0111|0133|00FE|00F0|00DF" ; +Maj["Macedonian (C)"] ="007E|0021|201E|201C|2019|0025|2018|0026|002A|0028|0029|005F|002B|0409|040A|0415|0420|0422|0405|0423|0418|041E|041F|0428|0403|0410|0421|0414|0424|0413|0425|0408|041A|041B|0427|040C|0401|0417|040F|0426|0412|0411|041D|041C|0416|003B|003A|003F|002A|005F|007B|007D" ; +Min["Macedonian (C)"] ="0060|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|002D|003D|0459|045A|0435|0440|0442|0455|0443|0438|043E|043F|0448|0453|0430|0441|0434|0444|0433|0445|0458|043A|043B|0447|045C|0451|0437|045F|0446|0432|0431|043D|043C|0436|002C|002E|002F|0027|002D|005B|005D" ; +Maj["Norwegian (L)"] ="00A7|0021|0022|0023|00A4|0025|0026|002F|0028|0029|003D|003F|0060|0051|0057|0045|0052|0054|0059|0055|0049|004F|0050|00C5|005E|0041|0053|0044|0046|0047|0048|004A|004B|00D8|00C6|00C4|003E|005A|0058|0043|0056|0042|004E|004D|003B|003A|002A|005F|007B|007D|005C|007E" ; +Min["Norwegian (L)"] ="00BD|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|002B|00B4|0071|0077|0065|0072|0074|0079|0075|0069|006F|0070|00E5|00A8|0061|0073|0064|0066|0067|0068|006A|006B|00F8|00E6|00E4|003C|007A|0078|0063|0076|0062|006E|006D|002C|002E|0027|002D|005B|005D|007C|0040" ; +Maj["Polish (L)"] ="002A|0021|0022|0023|00A4|0025|0026|002F|0028|0029|003D|003F|017A|0051|0057|0045|0052|0054|005A|0055|0049|004F|0050|0144|0107|0041|0053|0044|0046|0047|0048|004A|004B|004C|0141|0119|0059|0058|0043|0056|0042|004E|004D|003B|003A|005F|003C|005B|007B|02D9|00B4|02DB" ; +Min["Polish (L)"] ="0027|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|002B|00F3|0071|0077|0065|0072|0074|007A|0075|0069|006F|0070|017C|015B|0061|0073|0064|0066|0067|0068|006A|006B|006C|0142|0105|0079|0078|0063|0076|0062|006E|006D|002C|002E|002D|003E|005D|007D|02D9|00B4|02DB" ; +Maj["Russian (C)"] ="0401|0021|0040|0023|2116|0025|005E|0026|002A|0028|0029|005F|002B|0419|0426|0423|041A|0415|041D|0413|0428|0429|0417|0425|042A|0424|042B|0412|0410|041F|0420|041E|041B|0414|0416|042D|042F|0427|0421|041C|0418|0422|042C|0411|042E|003E|002E|003A|0022|005B|005D|003F" ; +Min["Russian (C)"] ="0451|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|002D|003D|0439|0446|0443|043A|0435|043D|0433|0448|0449|0437|0445|044A|0444|044B|0432|0430|043F|0440|043E|043B|0434|0436|044D|044F|0447|0441|043C|0438|0442|044C|0431|044E|003C|002C|003B|0027|007B|007D|002F" ; +Maj["Serbian (C)"] ="007E|0021|0022|0023|0024|0025|0026|002F|0028|0029|003D|003F|002A|0409|040A|0415|0420|0422|0417|0423|0418|041E|041F|0428|0402|0410|0421|0414|0424|0413|0425|0408|041A|041B|0427|040B|003E|0405|040F|0426|0412|0411|041D|041C|0416|003A|005F|002E|003A|0022|005B|005D" ; +Min["Serbian (C)"] ="0060|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|0027|002B|0459|045A|0435|0440|0442|0437|0443|0438|043E|043F|0448|0452|0430|0441|0434|0444|0433|0445|0458|043A|043B|0447|045B|003C|0455|045F|0446|0432|0431|043D|043C|0436|002E|002D|002C|003B|0027|007B|007D" ; +Maj["Serbian (L)"] ="007E|0021|0022|0023|0024|0025|0026|002F|0028|0029|003D|003F|002A|0051|0057|0045|0052|0054|005A|0055|0049|004F|0050|0160|0110|0041|0053|0044|0046|0047|0048|004A|004B|004C|010C|0106|003E|0059|0058|0043|0056|0042|004E|004D|017D|003A|005F|002E|003A|0022|005B|005D" ; +Min["Serbian (L)"] ="201A|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|0027|002B|0071|0077|0065|0072|0074|007A|0075|0069|006F|0070|0161|0111|0061|0073|0064|0066|0067|0068|006A|006B|006C|010D|0107|003C|0079|0078|0063|0076|0062|006E|006D|017E|002E|002D|002C|003B|0027|007B|007D" ; +Maj["Slovak (L)"] ="00B0|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|0025|02C7|0051|0057|0045|0052|0054|005A|0055|0049|004F|0050|002F|0028|0041|0053|0044|0046|0047|0048|004A|004B|004C|0022|0021|0059|0058|0043|0056|0042|004E|004D|003F|003A|005F|003C|005B|010F|0029|002A|0020" ; +Min["Slovak (L)"] ="003B|002B|013E|0161|010D|0165|017E|00FD|00E1|00ED|00E9|003D|00B4|0071|0077|0065|0072|0074|007A|0075|0069|006F|0070|00FA|00E4|0061|0073|0064|0066|0067|0068|006A|006B|006C|00F4|00A7|0079|0078|0063|0076|0062|006E|006D|002C|002E|002D|003E|005D|00F3|0148|0026|0020" ; +Maj["Spanish (L)"] ="00AA|0021|0022|00B7|0024|0025|0026|002F|0028|0029|003D|003F|00BF|0051|0057|0045|0052|0054|0059|0055|0049|004F|0050|005E|00A8|0041|0053|0044|0046|0047|0048|004A|004B|004C|00D1|00C7|005A|0058|0043|0056|0042|004E|004D|003B|003A|005F|003E|007C|0040|0023|007E|002A" ; +Min["Spanish (L)"] ="00BA|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|0027|00A1|0071|0077|0065|0072|0074|0079|0075|0069|006F|0070|0060|00B4|0061|0073|0064|0066|0067|0068|006A|006B|006C|00F1|00E7|007A|0078|0063|0076|0062|006E|006D|002C|002E|002D|003C|005C|0040|0023|007E|002B" ; +Maj["Ukrainian (C)"] ="0401|0021|0040|0023|2116|0025|005E|0026|002A|0028|0029|005F|002B|0419|0426|0423|041A|0415|041D|0413|0428|0429|0417|0425|0407|0424|0406|0412|0410|041F|0420|041E|041B|0414|0416|0404|0490|042F|0427|0421|041C|0418|0422|042C|0411|042E|002E|003A|0022|003C|003E|003F" ; +Min["Ukrainian (C)"] ="0451|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|002D|003D|0439|0446|0443|043A|0435|043D|0433|0448|0449|0437|0445|0457|0444|0456|0432|0430|043F|0440|043E|043B|0434|0436|0454|0491|044F|0447|0441|043C|0438|0442|044C|0431|044E|002C|003B|0027|007B|007D|002F" ; +Maj["Vietnamese (L)"] ="007E|0021|0040|0023|0024|0025|005E|0026|002A|0028|0029|005F|002B|0051|0057|0045|0052|0054|0059|0055|0049|004F|0050|01AF|01A0|0041|0053|0044|0046|0047|0048|004A|004B|004C|0102|00C2|005A|0058|0043|0056|0042|004E|004D|00CA|00D4|0110|003C|003E|003F|007D|003A|0022" ; +Min["Vietnamese (L)"] ="20AB|0031|0032|0033|0034|0035|0036|0037|0038|0039|0030|002D|003D|0071|0077|0065|0072|0074|0079|0075|0069|006F|0070|01B0|01A1|0061|0073|0064|0066|0067|0068|006A|006B|006C|0103|00E2|007A|0078|0063|0076|0062|006E|006D|00EA|00F4|0111|002C|002E|002F|007B|003B|0027" ; \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/diacritic.js b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/diacritic.js new file mode 100644 index 00000000..b00d32cd --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/diacritic.js @@ -0,0 +1,65 @@ +/* + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: diacritic.js + * Scripts for the fck_universalkey.html page. + * + * File Authors: + * Michel Staelens (michel.staelens@wanadoo.fr) + * Abdul-Aziz Al-Oraij (top7up@hotmail.com) + */ + +var dia = new Array() + +dia["0060"]=new Array();dia["00B4"]=new Array();dia["005E"]=new Array();dia["00A8"]=new Array();dia["007E"]=new Array();dia["00B0"]=new Array();dia["00B7"]=new Array();dia["00B8"]=new Array();dia["00AF"]=new Array();dia["02D9"]=new Array();dia["02DB"]=new Array();dia["02C7"]=new Array();dia["02D8"]=new Array();dia["02DD"]=new Array();dia["031B"]=new Array(); +dia["0060"]["0061"]="00E0";dia["00B4"]["0061"]="00E1";dia["005E"]["0061"]="00E2";dia["00A8"]["0061"]="00E4";dia["007E"]["0061"]="00E3";dia["00B0"]["0061"]="00E5";dia["00AF"]["0061"]="0101";dia["02DB"]["0061"]="0105";dia["02D8"]["0061"]="0103"; +dia["00B4"]["0063"]="0107";dia["005E"]["0063"]="0109";dia["00B8"]["0063"]="00E7";dia["02D9"]["0063"]="010B";dia["02C7"]["0063"]="010D"; +dia["02C7"]["0064"]="010F"; +dia["0060"]["0065"]="00E8";dia["00B4"]["0065"]="00E9";dia["005E"]["0065"]="00EA";dia["00A8"]["0065"]="00EB";dia["00AF"]["0065"]="0113";dia["02D9"]["0065"]="0117";dia["02DB"]["0065"]="0119";dia["02C7"]["0065"]="011B";dia["02D8"]["0065"]="0115"; +dia["005E"]["0067"]="011D";dia["00B8"]["0067"]="0123";dia["02D9"]["0067"]="0121";dia["02D8"]["0067"]="011F"; +dia["005E"]["0068"]="0125"; +dia["0060"]["0069"]="00EC";dia["00B4"]["0069"]="00ED";dia["005E"]["0069"]="00EE";dia["00A8"]["0069"]="00EF";dia["007E"]["0069"]="0129";dia["00AF"]["0069"]="012B";dia["02DB"]["0069"]="012F";dia["02D8"]["0069"]="012D"; +dia["005E"]["006A"]="0135"; +dia["00B8"]["006B"]="0137"; +dia["00B4"]["006C"]="013A";dia["00B7"]["006C"]="0140";dia["00B8"]["006C"]="013C";dia["02C7"]["006C"]="013E"; +dia["00B4"]["006E"]="0144";dia["007E"]["006E"]="00F1";dia["00B8"]["006E"]="0146";dia["02D8"]["006E"]="0148"; +dia["0060"]["006F"]="00F2";dia["00B4"]["006F"]="00F3";dia["005E"]["006F"]="00F4";dia["00A8"]["006F"]="00F6";dia["007E"]["006F"]="00F5";dia["00AF"]["006F"]="014D";dia["02D8"]["006F"]="014F";dia["02DD"]["006F"]="0151";dia["031B"]["006F"]="01A1"; +dia["00B4"]["0072"]="0155";dia["00B8"]["0072"]="0157";dia["02C7"]["0072"]="0159"; +dia["00B4"]["0073"]="015B";dia["005E"]["0073"]="015D";dia["00B8"]["0073"]="015F";dia["02C7"]["0073"]="0161"; +dia["00B8"]["0074"]="0163";dia["02C7"]["0074"]="0165"; +dia["0060"]["0075"]="00F9";dia["00B4"]["0075"]="00FA";dia["005E"]["0075"]="00FB";dia["00A8"]["0075"]="00FC";dia["007E"]["0075"]="0169";dia["00B0"]["0075"]="016F";dia["00AF"]["0075"]="016B";dia["02DB"]["0075"]="0173";dia["02D8"]["0075"]="016D";dia["02DD"]["0075"]="0171";dia["031B"]["0075"]="01B0"; +dia["005E"]["0077"]="0175"; +dia["00B4"]["0079"]="00FD";dia["005E"]["0079"]="0177";dia["00A8"]["0079"]="00FF"; +dia["00B4"]["007A"]="017A";dia["02D9"]["007A"]="017C";dia["02C7"]["007A"]="017E"; +dia["00B4"]["00E6"]="01FD"; +dia["00B4"]["00F8"]="01FF"; +dia["0060"]["0041"]="00C0";dia["00B4"]["0041"]="00C1";dia["005E"]["0041"]="00C2";dia["00A8"]["0041"]="00C4";dia["007E"]["0041"]="00C3";dia["00B0"]["0041"]="00C5";dia["00AF"]["0041"]="0100";dia["02DB"]["0041"]="0104";dia["02D8"]["0041"]="0102"; +dia["00B4"]["0043"]="0106";dia["005E"]["0043"]="0108";dia["00B8"]["0043"]="00C7";dia["02D9"]["0043"]="010A";dia["02C7"]["0043"]="010C"; +dia["02C7"]["0044"]="010E"; +dia["0060"]["0045"]="00C8";dia["00B4"]["0045"]="00C9";dia["005E"]["0045"]="00CA";dia["00A8"]["0045"]="00CB";dia["00AF"]["0045"]="0112";dia["02D9"]["0045"]="0116";dia["02DB"]["0045"]="0118";dia["02C7"]["0045"]="011A";dia["02D8"]["0045"]="0114"; +dia["005E"]["0047"]="011C";dia["00B8"]["0047"]="0122";dia["02D9"]["0047"]="0120";dia["02D8"]["0047"]="011E"; +dia["005E"]["0048"]="0124"; +dia["0060"]["0049"]="00CC";dia["00B4"]["0049"]="00CD";dia["005E"]["0049"]="00CE";dia["00A8"]["0049"]="00CF";dia["007E"]["0049"]="0128";dia["00AF"]["0049"]="012A";dia["02D9"]["0049"]="0130";dia["02DB"]["0049"]="012E";dia["02D8"]["0049"]="012C"; +dia["005E"]["004A"]="0134"; +dia["00B8"]["004B"]="0136"; +dia["00B4"]["004C"]="0139";dia["00B7"]["004C"]="013F";dia["00B8"]["004C"]="013B";dia["02C7"]["004C"]="013D"; +dia["00B4"]["004E"]="0143";dia["007E"]["004E"]="00D1";dia["00B8"]["004E"]="0145";dia["02D8"]["004E"]="0147"; +dia["0060"]["004F"]="00D2";dia["00B4"]["004F"]="00D3";dia["005E"]["004F"]="00D4";dia["00A8"]["004F"]="00D6";dia["007E"]["004F"]="00D5";dia["00AF"]["004F"]="014C";dia["02D8"]["004F"]="014E";dia["02DD"]["004F"]="0150";dia["031B"]["004F"]="01A0"; +dia["00B4"]["0052"]="0154";dia["00B8"]["0052"]="0156";dia["02C7"]["0052"]="0158"; +dia["00B4"]["0053"]="015A";dia["005E"]["0053"]="015C";dia["00B8"]["0053"]="015E";dia["02C7"]["0053"]="0160"; +dia["00B8"]["0054"]="0162";dia["02C7"]["0054"]="0164"; +dia["0060"]["0055"]="00D9";dia["00B4"]["0055"]="00DA";dia["005E"]["0055"]="00DB";dia["00A8"]["0055"]="00DC";dia["007E"]["0055"]="0168";dia["00B0"]["0055"]="016E";dia["00AF"]["0055"]="016A";dia["02DB"]["0055"]="0172";dia["02D8"]["0055"]="016C";dia["02DD"]["0055"]="0170";dia["031B"]["0055"]="01AF"; +dia["005E"]["0057"]="0174"; +dia["00B4"]["0059"]="00DD";dia["005E"]["0059"]="0176";dia["00A8"]["0059"]="0178"; +dia["00B4"]["005A"]="0179";dia["02D9"]["005A"]="017B";dia["02C7"]["005A"]="017D"; +dia["00B4"]["00C6"]="01FC"; +dia["00B4"]["00D8"]="01FE"; \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/dialogue.js b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/dialogue.js new file mode 100644 index 00000000..2d968b86 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/dialogue.js @@ -0,0 +1,31 @@ +/* + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: dialogue.js + * Scripts for the fck_universalkey.html page. + * + * File Authors: + * Michel Staelens (michel.staelens@wanadoo.fr) + * Bernadette Cierzniak + * Abdul-Aziz Al-Oraij (top7up@hotmail.com) + * Frederico Caldeira Knabben (fredck@fckeditor.net) + */ + +function afficher(txt) +{ + document.getElementById( 'uni_area' ).value = txt ; +} + +function rechercher() +{ + return document.getElementById( 'uni_area' ).value ; +} \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/fck_universalkey.css b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/fck_universalkey.css new file mode 100644 index 00000000..c17c5071 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/fck_universalkey.css @@ -0,0 +1,62 @@ +/* + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: fck_universalkey.css + * CSS styles for the Universal Keyboard. + * + * File Authors: + * Michel Staelens (michel.staelens@wanadoo.fr) + * Bernadette Cierzniak + * Abdul-Aziz Al-Oraij (top7up@hotmail.com) + */ + +BODY, TEXTAREA, INPUT, TD, SELECT +{ + font-family: Tahoma,verdana,arial,sans-serif; +} +DIV +{ + position: absolute; +} +.simple +{ + font-size: 11pt; +} +.double +{ + font-size: 9pt; +} +.simpledia +{ + color: red; + font-size: 11pt; +} +.doubledia +{ + color: red; + font-size: 9pt; +} +.action +{ + color: white; + font-size: 7pt; +} +.clavier +{ + color: blue; + font-size: 7pt; +} +.sign +{ + color: gray; + font-size: 7pt; +} diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/keyboard_layout.gif b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/keyboard_layout.gif new file mode 100644 index 0000000000000000000000000000000000000000..2183cc7156a881b992bf8b01638cdf5b985074e0 GIT binary patch literal 3056 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 literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/multihexa.js b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/multihexa.js new file mode 100644 index 00000000..8c2bfc33 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/dialog/fck_universalkey/multihexa.js @@ -0,0 +1,309 @@ +/* + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: multihexa.js + * Scripts for the fck_universalkey.html page. + * Definition des 104 caracteres en hexa unicode. + * + * File Authors: + * Michel Staelens (michel.staelens@wanadoo.fr) + * Bernadette Cierzniak + * Abdul-Aziz Al-Oraij (top7up@hotmail.com) + */ + +var caps=0, lock=0, hexchars="0123456789ABCDEF", accent="0000", keydeb=0 +var key=new Array();j=0;for (i in Maj){key[j]=i;j++} +var ns6=((!document.all)&&(document.getElementById)) +var ie=document.all + +var langue=getCk(); +if (langue==""){ + langue=key[keydeb] +} +CarMaj=Maj[langue].split("|");CarMin=Min[langue].split("|") + +/*unikey*/ +var posUniKeyLeft=0, posUniKeyTop=0 +if (ns6){posUniKeyLeft=0;posUniKeyTop=60} +else if (ie){posUniKeyLeft=0;posUniKeyTop=60} +tracer("fond",posUniKeyLeft,posUniKeyTop,'
',"sign") +/*touches*/ +var posX=new Array(0,28,56,84,112,140,168,196,224,252,280,308,336,42,70,98,126,154,182,210,238,266,294,322,350,50,78,106,134,162,190,218,246,274,302,330,64,92,120,148,176,204,232,260,288,316,28,56,84,294,322,350) +var posY=new Array(14,14,14,14,14,14,14,14,14,14,14,14,14,42,42,42,42,42,42,42,42,42,42,42,42,70,70,70,70,70,70,70,70,70,70,70,98,98,98,98,98,98,98,98,98,98,126,126,126,126,126,126) +var nbTouches=52 +for (i=0;i Lock","Enter","Shift","Shift","<|<","Space",">|>") +var effet=new Array("keyscroll(-3)","keyscroll(3)","faire(\"del\")","RAZ()","faire(\"bck\")","bloq()","faire(\"\\n\")","haut()","haut()","faire(\"ar\")","faire(\" \")","faire(\"av\")") +var nbActions=12 +for (i=0;i') +document.write('') +for (i=0;i') +} +for (i=0;i') +} +for (i=0;i<4;i++){ + document.write('') +} +document.write('') + +/*fonctions*/ +function ecrire(i){ + txt=rechercher()+"|";subtxt=txt.split("|") + ceci=(lock==1)?CarMaj[i]:((caps==1)?CarMaj[i]:CarMin[i]) + if (test(ceci)){subtxt[0]+=cardia(ceci);distinguer(false)} + else if(dia[accent]!=null&&dia[hexa(ceci)]!=null){distinguer(false);accent=hexa(ceci);distinguer(true)} + else if(dia[accent]!=null){subtxt[0]+=fromhexby4tocar(accent)+ceci;distinguer(false)} + else if(dia[hexa(ceci)]!=null){accent=hexa(ceci);distinguer(true)} + else {subtxt[0]+=ceci} + txt=subtxt[0]+"|"+subtxt[1] + afficher(txt) + if (caps==1){caps=0;MinusMajus()} +} +function faire(ceci){ + txt=rechercher()+"|";subtxt=txt.split("|") + l0=subtxt[0].length + l1=subtxt[1].length + c1=subtxt[0].substring(0,(l0-2)) + c2=subtxt[0].substring(0,(l0-1)) + c3=subtxt[1].substring(0,1) + c4=subtxt[1].substring(0,2) + c5=subtxt[0].substring((l0-2),l0) + c6=subtxt[0].substring((l0-1),l0) + c7=subtxt[1].substring(1,l1) + c8=subtxt[1].substring(2,l1) + if(dia[accent]!=null){if(ceci==" "){ceci=fromhexby4tocar(accent)}distinguer(false)} + switch (ceci){ + case("av") :if(escape(c4)!="%0D%0A"){txt=subtxt[0]+c3+"|"+c7}else{txt=subtxt[0]+c4+"|"+c8}break + case("ar") :if(escape(c5)!="%0D%0A"){txt=c2+"|"+c6+subtxt[1]}else{txt=c1+"|"+c5+subtxt[1]}break + case("bck"):if(escape(c5)!="%0D%0A"){txt=c2+"|"+subtxt[1]}else{txt=c1+"|"+subtxt[1]}break + case("del"):if(escape(c4)!="%0D%0A"){txt=subtxt[0]+"|"+c7}else{txt=subtxt[0]+"|"+c8}break + default:txt=subtxt[0]+ceci+"|"+subtxt[1];break + } + afficher(txt) +} +function RAZ(){txt="";if(dia[accent]!=null){distinguer(false)}afficher(txt)} +function haut(){caps=1;MinusMajus()} +function bloq(){lock=(lock==1)?0:1;MinusMajus()} + +/*fonctions de traitement du unikey*/ +function tracer(nom,gauche,haut,ceci,classe){ceci=""+ceci+"";document.write('
'+ceci+'
');if (ns6){document.getElementById(nom).style.left=gauche+"px";document.getElementById(nom).style.top=haut+"px";}else if (ie){document.all(nom).style.left=gauche;document.all(nom).style.top=haut}} +function retracer(nom,ceci,classe){ceci=""+ceci+"";if (ns6){document.getElementById(nom).innerHTML=ceci}else if (ie){doc=document.all(nom);doc.innerHTML=ceci}} +function keyscroll(n){ + keydeb+=n + if (keydeb<0){ + keydeb=0 + } + if (keydeb>key.length-4){ + keydeb=key.length-4 + } + for (i=keydeb;i=0;a--){out+=Math.pow(16,inval.length-a-1)*hexchars.indexOf(inval.charAt(a))}return out} +function fromhexby4tocar(ceci){out4=new String();for (l=0;l-1)|(langue!="Arabic")) return true; + + if (!e) var e = window.event; + if (e.keyCode) keyCode = e.keyCode; + else if (e.which) keyCode = e.which; + var character = String.fromCharCode(keyCode); + + entry = true; + cont=e.srcElement || e.currentTarget || e.target; + if (keyCode>64 && keyCode<91) { + entry=false; + source='ش لاؤ ي ث ب ل ا ه ت ن م ة ى خ ح ض ق س ف ع ر ص ء غ ئ '; + shsource='ِ لآ} ] ُ [ لأأ ÷ ـ ، / آ × ؛ َ ٌ ٍ لإ { ً ْ إ ~'; + + if (e.shiftKey) cont.value += shsource.substr((keyCode-64)*2-2,2); + else + cont.value += source.substr((keyCode-64)*2-2,2); + if (cont.value.substr(cont.value.length-1,1)==' ') cont.value=cont.value.substr(0,cont.value.length-1); + } + if (e.shiftKey) { + if (keyCode==186) {cont.value += ':';entry=false;} + if (keyCode==188) {cont.value += ',';entry=false;} + if (keyCode==190) {cont.value += '.';entry=false;} + if (keyCode==191) {cont.value += '؟';entry=false;} + if (keyCode==192) {cont.value += 'ّ';entry=false;} + if (keyCode==219) {cont.value += '<';entry=false;} + if (keyCode==221) {cont.value += '>';entry=false;} + } else { + if (keyCode==186||keyCode==59) {cont.value += 'ك';entry=false;} + if (keyCode==188) {cont.value += 'و';entry=false;} + if (keyCode==190) {cont.value += 'ز';entry=false;} + if (keyCode==191) {cont.value += 'ظ';entry=false;} + if (keyCode==192) {cont.value += 'ذ';entry=false;} + if (keyCode==219) {cont.value += 'ج';entry=false;} + if (keyCode==221) {cont.value += 'د';entry=false;} + if (keyCode==222) {cont.value += 'ط';entry=false;} + } + return entry; +} +function hold_it(e){ + if ((document.layers)|(navigator.userAgent.indexOf("MSIE 4")>-1)|(langue!="Arabic")) return true; + + var keyCode; + if (!e) var e = window.event; + if (e.keyCode) keyCode = e.keyCode; + else if (e.which) keyCode = e.which; + var character = String.fromCharCode(keyCode); + switch(keyCode){ + case 186: + case 188: + case 190: + case 191: + case 192: + case 219: + case 221: + case 222: + case 116: + case 59: + case 47: + case 46: + case 44: + case 39: + return false; + case 92: + return true; + } + if (keyCode<63) return true; + return false; + } + +var obj = document.getElementById( 'uni_area' ); +if ( obj && langue=="Arabic"){ + with (navigator) { + if (appName=="Netscape") + obj.onkeypress = hold_it; + } + obj.onkeydown = arkey; +} +// Arabic Keystroke Translator End \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/browser.css b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/browser.css new file mode 100644 index 00000000..32714a87 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/browser.css @@ -0,0 +1,84 @@ +/* + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: browser.css + * CSS styles used by all pages that compose the File Browser. + * + * File Authors: + * Frederico Caldeira Knabben (fredck@fckeditor.net) + */ + +body +{ + background-color: #f1f1e3; +} + +form +{ + margin: 0px 0px 0px 0px ; + padding: 0px 0px 0px 0px ; +} + +.Frame +{ + background-color: #f1f1e3; + border-color: #f1f1e3; + border-right: thin inset; + border-top: thin inset; + border-left: thin inset; + border-bottom: thin inset; +} + +body.FileArea +{ + + background-color: #ffffff; +} + +body, td, input, select +{ + font-size: 11px; + font-family: 'Microsoft Sans Serif' , Arial, Helvetica, Verdana; +} + +.ActualFolder +{ + font-weight: bold; + font-size: 14px; +} + +.PopupButtons +{ + border-top: #d5d59d 1px solid; + background-color: #e3e3c7; + padding: 7px 10px 7px 10px; +} + +.Button, button +{ + border-right: #737357 1px solid; + border-top: #737357 1px solid; + border-left: #737357 1px solid; + color: #3b3b1f; + border-bottom: #737357 1px solid; + background-color: #c7c78f; +} + +.FolderListCurrentFolder img +{ + background-image: url(images/FolderOpened.gif); +} + +.FolderListFolder img +{ + background-image: url(images/Folder.gif); +} \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/browser.html b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/browser.html new file mode 100644 index 00000000..5b82173d --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/browser.html @@ -0,0 +1,148 @@ + + + + + FCKeditor - Resources Browser + + + + + + + + + + + + + + + + + + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/basexml.asp b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/basexml.asp new file mode 100644 index 00000000..7441e488 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/basexml.asp @@ -0,0 +1,58 @@ + +<% + +Sub SetXmlHeaders() + ' Cleans the response buffer. + Response.Clear() + + ' Prevent the browser from caching the result. + Response.CacheControl = "no-cache" + + ' Set the response format. + Response.CharSet = "UTF-8" + Response.ContentType = "text/xml" +End Sub + +Sub CreateXmlHeader( command, resourceType, currentFolder ) + ' Create the XML document header. + Response.Write "" + + ' Create the main "Connector" node. + Response.Write "" + + ' Add the current folder node. + Response.Write "" +End Sub + +Sub CreateXmlFooter() + Response.Write "" +End Sub + +Sub SendError( number, text ) + SetXmlHeaders + + ' Create the XML document header. + Response.Write "" + + Response.Write "" + + Response.End +End Sub +%> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/class_upload.asp b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/class_upload.asp new file mode 100644 index 00000000..dcfe2ba9 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/class_upload.asp @@ -0,0 +1,230 @@ + +<% +'********************************************** +' File: NetRube_Upload.asp +' Version: NetRube Upload Class Version 2.1 Build 20050228 +' Author: NetRube +' Email: NetRube@126.com +' Date: 02/28/2005 +' Comments: The code for the Upload. +' This can free usage, but please +' not to delete this copyright information. +' If you have a modification version, +' Please send out a duplicate to me. +'********************************************** +' 文件名: NetRube_Upload.asp +' 版本: NetRube Upload Class Version 2.1 Build 20050228 +' 作者: NetRube(网络乡巴佬) +' 电子邮件: NetRube@126.com +' 日期: 2005年02月28日 +' 声明: 文件上传类 +' 本上传类可以自由使用,但请保留此版权声明信息 +' 如果您对本上传类进行修改增强, +' 请发送一份给俺。 +'********************************************** + +Class NetRube_Upload + + Public File, Form + Private oSourceData + Private nMaxSize, nErr, sAllowed, sDenied + + Private Sub Class_Initialize + nErr = 0 + nMaxSize = 1048576 + + Set File = Server.CreateObject("Scripting.Dictionary") + File.CompareMode = 1 + Set Form = Server.CreateObject("Scripting.Dictionary") + Form.CompareMode = 1 + + Set oSourceData = Server.CreateObject("ADODB.Stream") + oSourceData.Type = 1 + oSourceData.Mode = 3 + oSourceData.Open + End Sub + + Private Sub Class_Terminate + Form.RemoveAll + Set Form = Nothing + File.RemoveAll + Set File = Nothing + + oSourceData.Close + Set oSourceData = Nothing + End Sub + + Public Property Get Version + Version = "NetRube Upload Class Version 1.0 Build 20041218" + End Property + + Public Property Get ErrNum + ErrNum = nErr + End Property + + Public Property Let MaxSize(nSize) + nMaxSize = nSize + End Property + + Public Property Let Allowed(sExt) + sAllowed = sExt + End Property + + Public Property Let Denied(sExt) + sDenied = sExt + End Property + + Public Sub GetData + Dim aCType + aCType = Split(Request.ServerVariables("HTTP_CONTENT_TYPE"), ";") + If aCType(0) <> "multipart/form-data" Then + nErr = 1 + Exit Sub + End If + + Dim nTotalSize + nTotalSize = Request.TotalBytes + If nTotalSize < 1 Then + nErr = 2 + Exit Sub + End If + If nMaxSize > 0 And nTotalSize > nMaxSize Then + nErr = 3 + Exit Sub + End If + + oSourceData.Write Request.BinaryRead(nTotalSize) + oSourceData.Position = 0 + + Dim oTotalData, oFormStream, sFormHeader, sFormName, bCrLf, nBoundLen, nFormStart, nFormEnd, nPosStart, nPosEnd, sBoundary + + oTotalData = oSourceData.Read + bCrLf = ChrB(13) & ChrB(10) + sBoundary = MidB(oTotalData, 1, InStrB(1, oTotalData, bCrLf) - 1) + nBoundLen = LenB(sBoundary) + 2 + nFormStart = nBoundLen + + Set oFormStream = Server.CreateObject("ADODB.Stream") + + Do While (nFormStart + 2) < nTotalSize + nFormEnd = InStrB(nFormStart, oTotalData, bCrLf & bCrLf) + 3 + + With oFormStream + .Type = 1 + .Mode = 3 + .Open + oSourceData.Position = nFormStart + oSourceData.CopyTo oFormStream, nFormEnd - nFormStart + .Position = 0 + .Type = 2 + .CharSet = "UTF-8" + sFormHeader = .ReadText + .Close + End With + + nFormStart = InStrB(nFormEnd, oTotalData, sBoundary) - 1 + nPosStart = InStr(22, sFormHeader, " name=", 1) + 7 + nPosEnd = InStr(nPosStart, sFormHeader, """") + sFormName = Mid(sFormHeader, nPosStart, nPosEnd - nPosStart) + + If InStr(45, sFormHeader, " filename=", 1) > 0 Then + Set File(sFormName) = New NetRube_FileInfo + File(sFormName).FormName = sFormName + File(sFormName).Start = nFormEnd + File(sFormName).Size = nFormStart - nFormEnd - 2 + nPosStart = InStr(nPosEnd, sFormHeader, " filename=", 1) + 11 + nPosEnd = InStr(nPosStart, sFormHeader, """") + File(sFormName).ClientPath = Mid(sFormHeader, nPosStart, nPosEnd - nPosStart) + File(sFormName).Name = Mid(File(sFormName).ClientPath, InStrRev(File(sFormName).ClientPath, "\") + 1) + File(sFormName).Ext = LCase(Mid(File(sFormName).Name, InStrRev(File(sFormName).Name, ".") + 1)) + nPosStart = InStr(nPosEnd, sFormHeader, "Content-Type: ", 1) + 14 + nPosEnd = InStr(nPosStart, sFormHeader, vbCr) + File(sFormName).MIME = Mid(sFormHeader, nPosStart, nPosEnd - nPosStart) + Else + With oFormStream + .Type = 1 + .Mode = 3 + .Open + oSourceData.Position = nPosEnd + oSourceData.CopyTo oFormStream, nFormStart - nFormEnd - 2 + .Position = 0 + .Type = 2 + .CharSet = "UTF-8" + Form(sFormName) = .ReadText + .Close + End With + End If + + nFormStart = nFormStart + nBoundLen + Loop + + oTotalData = "" + Set oFormStream = Nothing + End Sub + + Public Sub SaveAs(sItem, sFileName) + If File(sItem).Size < 1 Then + nErr = 2 + Exit Sub + End If + + If Not IsAllowed(File(sItem).Ext) Then + nErr = 4 + Exit Sub + End If + + Dim oFileStream + Set oFileStream = Server.CreateObject("ADODB.Stream") + With oFileStream + .Type = 1 + .Mode = 3 + .Open + oSourceData.Position = File(sItem).Start + oSourceData.CopyTo oFileStream, File(sItem).Size + .Position = 0 + .SaveToFile sFileName, 2 + .Close + End With + Set oFileStream = Nothing + End Sub + + Private Function IsAllowed(sExt) + Dim oRE + Set oRE = New RegExp + oRE.IgnoreCase = True + oRE.Global = True + + If sDenied = "" Then + oRE.Pattern = sAllowed + IsAllowed = (sAllowed = "") Or oRE.Test(sExt) + Else + oRE.Pattern = sDenied + IsAllowed = Not oRE.Test(sExt) + End If + + Set oRE = Nothing + End Function +End Class + +Class NetRube_FileInfo + Dim FormName, ClientPath, Path, Name, Ext, Content, Size, MIME, Start +End Class +%> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/commands.asp b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/commands.asp new file mode 100644 index 00000000..e4d269ca --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/commands.asp @@ -0,0 +1,179 @@ + +<% +Sub GetFolders( resourceType, currentFolder ) + ' Map the virtual path to the local server path. + Dim sServerDir + sServerDir = ServerMapFolder( resourceType, currentFolder ) + + ' Open the "Folders" node. + Response.Write "" + + Dim oFSO, oCurrentFolder, oFolders, oFolder + Set oFSO = Server.CreateObject( "Scripting.FileSystemObject" ) + Set oCurrentFolder = oFSO.GetFolder( sServerDir ) + Set oFolders = oCurrentFolder.SubFolders + + For Each oFolder in oFolders + Response.Write "" + Next + + Set oFSO = Nothing + + ' Close the "Folders" node. + Response.Write "" +End Sub + +Sub GetFoldersAndFiles( resourceType, currentFolder ) + ' Map the virtual path to the local server path. + Dim sServerDir + sServerDir = ServerMapFolder( resourceType, currentFolder ) + + Dim oFSO, oCurrentFolder, oFolders, oFolder, oFiles, oFile + Set oFSO = Server.CreateObject( "Scripting.FileSystemObject" ) + Set oCurrentFolder = oFSO.GetFolder( sServerDir ) + Set oFolders = oCurrentFolder.SubFolders + Set oFiles = oCurrentFolder.Files + + ' Open the "Folders" node. + Response.Write "" + + For Each oFolder in oFolders + Response.Write "" + Next + + ' Close the "Folders" node. + Response.Write "" + + ' Open the "Files" node. + Response.Write "" + + For Each oFile in oFiles + Dim iFileSize + iFileSize = Round( oFile.size / 1024 ) + If ( iFileSize < 1 AND oFile.size <> 0 ) Then iFileSize = 1 + + Response.Write "" + Next + + ' Close the "Files" node. + Response.Write "" +End Sub + +Sub CreateFolder( resourceType, currentFolder ) + Dim sErrorNumber + + Dim sNewFolderName + sNewFolderName = Request.QueryString( "NewFolderName" ) + + If ( sNewFolderName = "" OR InStr( 1, sNewFolderName, ".." ) > 0 ) Then + sErrorNumber = "102" + Else + ' Map the virtual path to the local server path of the current folder. + Dim sServerDir + sServerDir = ServerMapFolder( resourceType, currentFolder & "/" & sNewFolderName ) + + On Error Resume Next + + CreateServerFolder sServerDir + + Dim iErrNumber, sErrDescription + iErrNumber = err.number + sErrDescription = err.Description + + On Error Goto 0 + + Select Case iErrNumber + Case 0 + sErrorNumber = "0" + Case 52 + sErrorNumber = "102" ' Invalid Folder Name. + Case 70 + sErrorNumber = "103" ' Security Error. + Case 76 + sErrorNumber = "102" ' Path too long. + Case Else + sErrorNumber = "110" + End Select + End If + + ' Create the "Error" node. + Response.Write "" +End Sub + +Sub FileUpload( resourceType, currentFolder ) + Dim oUploader + Set oUploader = New NetRube_Upload + oUploader.MaxSize = 0 + oUploader.Allowed = ConfigAllowedExtensions.Item( resourceType ) + oUploader.Denied = ConfigDeniedExtensions.Item( resourceType ) + oUploader.GetData + + Dim sErrorNumber + sErrorNumber = "0" + + Dim sFileName, sOriginalFileName, sExtension + sFileName = "" + + If oUploader.ErrNum > 1 Then + sErrorNumber = "202" + Else + ' Map the virtual path to the local server path. + Dim sServerDir + sServerDir = ServerMapFolder( resourceType, currentFolder ) + + Dim oFSO + Set oFSO = Server.CreateObject( "Scripting.FileSystemObject" ) + + ' Get the uploaded file name. + sFileName = oUploader.File( "NewFile" ).Name + sExtension = oUploader.File( "NewFile" ).Ext + sOriginalFileName = sFileName + + Dim iCounter + iCounter = 0 + + Do While ( True ) + Dim sFilePath + sFilePath = sServerDir & sFileName + + If ( oFSO.FileExists( sFilePath ) ) Then + iCounter = iCounter + 1 + sFileName = RemoveExtension( sOriginalFileName ) & "(" & iCounter & ")." & sExtension + sErrorNumber = "201" + Else + oUploader.SaveAs "NewFile", sFilePath + If oUploader.ErrNum > 0 Then sErrorNumber = "202" + Exit Do + End If + Loop + End If + + Set oUploader = Nothing + + Response.Clear + + Response.Write "" + + Response.End +End Sub +%> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/config.asp b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/config.asp new file mode 100644 index 00000000..802a89fa --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/config.asp @@ -0,0 +1,45 @@ + +<% + +' SECURITY: You must explicitelly enable this "connector" (set it to "True"). +Dim ConfigIsEnabled +ConfigIsEnabled = False + +' Path to user files relative to the document root. +Dim ConfigUserFilesPath +ConfigUserFilesPath = "/UserFiles/" + +Dim ConfigAllowedExtensions, ConfigDeniedExtensions +Set ConfigAllowedExtensions = CreateObject( "Scripting.Dictionary" ) +Set ConfigDeniedExtensions = CreateObject( "Scripting.Dictionary" ) + +ConfigAllowedExtensions.Add "File", "" +ConfigDeniedExtensions.Add "File", "php|asp|aspx|ascx|jsp|cfm|cfc|pl|bat|exe|com|dll|vbs|js|reg" + +ConfigAllowedExtensions.Add "Image", "jpg|gif|jpeg|png|bmp" +ConfigDeniedExtensions.Add "Image", "" + +ConfigAllowedExtensions.Add "Flash", "swf|fla" +ConfigDeniedExtensions.Add "Flash", "" + +ConfigAllowedExtensions.Add "Media", "swf|fla|jpg|gif|jpeg|png|avi|mpg|mpeg|mp(1-4)|wma|wmv|wav|mid|midi|rmi|rm|ram|rmvb|mov|qt" +ConfigDeniedExtensions.Add "Media", "" + +%> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/connector.asp b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/connector.asp new file mode 100644 index 00000000..e11c9235 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/connector.asp @@ -0,0 +1,119 @@ +<%@ CodePage=65001 Language="VBScript"%> +<% +Option Explicit +%> + + + + + + + +<% + +If ( ConfigIsEnabled = False ) Then + SendError 1, "This connector is disabled. Please check the ""editor/filemanager/browser/default/connectors/asp/config.asp"" file" +End If + +' Get the "UserFiles" path. +Dim sUserFilesPath + +If ( Not IsEmpty( ConfigUserFilesPath ) ) Then + sUserFilesPath = ConfigUserFilesPath + + If ( Right( sUserFilesPath, 1 ) <> "/" ) Then + sUserFilesPath = sUserFilesPath & "/" + End If +Else + sUserFilesPath = "/UserFiles/" +End If + +' Map the "UserFiles" path to a local directory. +Dim sUserFilesDirectory +sUserFilesDirectory = Server.MapPath( sUserFilesPath ) + +If ( Right( sUserFilesDirectory, 1 ) <> "\" ) Then + sUserFilesDirectory = sUserFilesDirectory & "\" +End If + +DoResponse + +Sub DoResponse() + Dim sCommand, sResourceType, sCurrentFolder + + ' Get the main request information. + sCommand = Request.QueryString("Command") + If ( sCommand = "" ) Then Exit Sub + + sResourceType = Request.QueryString("Type") + If ( sResourceType = "" ) Then Exit Sub + + sCurrentFolder = Request.QueryString("CurrentFolder") + If ( sCurrentFolder = "" ) Then Exit Sub + + ' Check if it is an allower resource type. + if ( Not IsAllowedType( sResourceType ) ) Then Exit Sub + + ' Check the current folder syntax (must begin and start with a slash). + If ( Right( sCurrentFolder, 1 ) <> "/" ) Then sCurrentFolder = sCurrentFolder & "/" + If ( Left( sCurrentFolder, 1 ) <> "/" ) Then sCurrentFolder = "/" & sCurrentFolder + + ' Check for invalid folder paths (..) + If ( InStr( 1, sCurrentFolder, ".." ) <> 0 OR InStr( 1, sResourceType, ".." ) <> 0 ) Then + SendError 102, "" + End If + + ' File Upload doesn't have to Return XML, so it must be intercepted before anything. + If ( sCommand = "FileUpload" ) Then + FileUpload sResourceType, sCurrentFolder + Exit Sub + End If + + SetXmlHeaders + + CreateXmlHeader sCommand, sResourceType, sCurrentFolder + + ' Execute the required command. + Select Case sCommand + Case "GetFolders" + GetFolders sResourceType, sCurrentFolder + Case "GetFoldersAndFiles" + GetFoldersAndFiles sResourceType, sCurrentFolder + Case "CreateFolder" + CreateFolder sResourceType, sCurrentFolder + End Select + + CreateXmlFooter + + Response.End +End Sub + +Function IsAllowedType( resourceType ) + Dim oRE + Set oRE = New RegExp + oRE.IgnoreCase = True + oRE.Global = True + oRE.Pattern = "^(File|Image|Flash|Media)$" + + IsAllowedType = oRE.Test( resourceType ) + + Set oRE = Nothing +End Function +%> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/io.asp b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/io.asp new file mode 100644 index 00000000..572a5ec2 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/io.asp @@ -0,0 +1,85 @@ + +<% +Function GetUrlFromPath( resourceType, folderPath ) + If resourceType = "" Then + GetUrlFromPath = RemoveFromEnd( sUserFilesPath, "/" ) & folderPath + Else + GetUrlFromPath = sUserFilesPath & resourceType & folderPath + End If +End Function + +Function RemoveExtension( fileName ) + RemoveExtension = Left( fileName, InStrRev( fileName, "." ) - 1 ) +End Function + +Function ServerMapFolder( resourceType, folderPath ) + ' Get the resource type directory. + Dim sResourceTypePath + sResourceTypePath = sUserFilesDirectory & resourceType & "\" + + ' Ensure that the directory exists. + CreateServerFolder sResourceTypePath + + ' Return the resource type directory combined with the required path. + ServerMapFolder = sResourceTypePath & RemoveFromStart( folderPath, "/" ) +End Function + +Sub CreateServerFolder( folderPath ) + Dim oFSO + Set oFSO = Server.CreateObject( "Scripting.FileSystemObject" ) + + Dim sParent + sParent = oFSO.GetParentFolderName( folderPath ) + + ' Check if the parent exists, or create it. + If ( NOT oFSO.FolderExists( sParent ) ) Then CreateServerFolder( sParent ) + + If ( oFSO.FolderExists( folderPath ) = False ) Then + oFSO.CreateFolder( folderPath ) + End If + + Set oFSO = Nothing +End Sub + +Function IsAllowedExt( extension, resourceType ) + Dim oRE + Set oRE = New RegExp + oRE.IgnoreCase = True + oRE.Global = True + + Dim sAllowed, sDenied + sAllowed = ConfigAllowedExtensions.Item( resourceType ) + sDenied = ConfigDeniedExtensions.Item( resourceType ) + + IsAllowedExt = True + + If sDenied <> "" Then + oRE.Pattern = sDenied + IsAllowedExt = Not oRE.Test( extension ) + End If + + If IsAllowedExt And sAllowed <> "" Then + oRE.Pattern = sAllowed + IsAllowedExt = oRE.Test( extension ) + End If + + Set oRE = Nothing +End Function +%> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/util.asp b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/util.asp new file mode 100644 index 00000000..e5dd3044 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/asp/util.asp @@ -0,0 +1,51 @@ + +<% +Function RemoveFromStart( sourceString, charToRemove ) + Dim oRegex + Set oRegex = New RegExp + oRegex.Pattern = "^" & charToRemove & "+" + + RemoveFromStart = oRegex.Replace( sourceString, "" ) +End Function + +Function RemoveFromEnd( sourceString, charToRemove ) + Dim oRegex + Set oRegex = New RegExp + oRegex.Pattern = charToRemove & "+$" + + RemoveFromEnd = oRegex.Replace( sourceString, "" ) +End Function + +Function ConvertToXmlAttribute( value ) + ConvertToXmlAttribute = Replace( value, "&", "&" ) +End Function + +Function InArray( value, sourceArray ) + Dim i + For i = 0 to UBound( sourceArray ) + If sourceArray(i) = value Then + InArray = True + Exit Function + End If + Next + InArray = False +End Function + +%> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx new file mode 100644 index 00000000..e27bcef2 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx @@ -0,0 +1,26 @@ +<%@ Page language="c#" Inherits="FredCK.FCKeditorV2.FileBrowserConnector" AutoEventWireup="false" %> +<%-- + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2005 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: connector.aspx + * This is the File Browser Connector for ASP.NET. + * + * The code of this page if included in the FCKeditor.Net package, + * in the FredCK.FCKeditorV2.dll assemblyfile. So to use it you must + * include that DLL in your "bin" directory. + * + * To download the FCKeditor.Net package, go to our official web site: + * http://www.fckeditor.net + * + * File Authors: + * Frederico Caldeira Knabben (fredck@fckeditor.net) +--%> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/cfm/config.cfm b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/cfm/config.cfm new file mode 100644 index 00000000..1a744988 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/cfm/config.cfm @@ -0,0 +1,80 @@ + + + + config = structNew(); + + // SECURITY: You must explicitly enable this "connector". (Set enabled to "true") + config.enabled = false; + + config.userFilesPath = "/UserFiles/"; + + config.serverPath = ""; // use this to force the server path if FCKeditor is not running directly off the root of the application or the FCKeditor directory in the URL is a virtual directory or a symbolic link / junction + + config.allowedExtensions = structNew(); + config.deniedExtensions = structNew(); + + // config.allowedExtensions["File"] = "doc,rtf,pdf,ppt,pps,xls,csv,vnd,zip"; + config.allowedExtensions["File"] = ""; + config.deniedExtensions["File"] = "php,asp,aspx,ascx,jsp,cfm,cfc,pl,bat,exe,com,dll,vbs,js,reg"; + + config.allowedExtensions["Image"] = "png,gif,jpg,jpeg,bmp"; + config.deniedExtensions["Image"] = ""; + + config.allowedExtensions["Flash"] = "swf,fla"; + config.deniedExtensions["Flash"] = ""; + + config.allowedExtensions["Media"] = "swf,fla,jpg,gif,jpeg,png,avi,mpg,mpeg,mp3,mp4,m4a,wma,wmv,wav,mid,midi,rmi,rm,ram,rmvb,mov,qt"; + config.deniedExtensions["Media"] = ""; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + function structCopyKeys(stFrom, stTo) { + for ( key in stFrom ) { + if ( isStruct(stFrom[key]) ) { + structCopyKeys(stFrom[key],stTo[key]); + } else { + stTo[key] = stFrom[key]; + } + } + } + structCopyKeys(FCKeditor, config); + + + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/cfm/connector.cfm b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/cfm/connector.cfm new file mode 100644 index 00000000..d10793c6 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/cfm/connector.cfm @@ -0,0 +1,364 @@ + + + + + + + + + + + + userFilesPath = config.userFilesPath; + lAllowedExtensions = config.allowedExtensions[url.type]; + lDeniedExtensions = config.deniedExtensions[url.type]; + + // make sure the user files path is correctly formatted + userFilesPath = replace(userFilesPath, "\", "/", "ALL"); + userFilesPath = replace(userFilesPath, '//', '/', 'ALL'); + if ( right(userFilesPath,1) neq "/" ) { + userFilesPath = userFilesPath & "/"; + } + if ( left(userFilesPath,1) neq "/" ) { + userFilesPath = "/" & userFilesPath; + } + + // make sure the current folder is correctly formatted + url.currentFolder = replace(url.currentFolder, "\", "/", "ALL"); + url.currentFolder = replace(url.currentFolder, '//', '/', 'ALL'); + if ( right(url.currentFolder,1) neq "/" ) { + url.currentFolder = url.currentFolder & "/"; + } + if ( left(url.currentFolder,1) neq "/" ) { + url.currentFolder = "/" & url.currentFolder; + } + + if ( find("/",getBaseTemplatePath()) neq 0 ) { + fs = "/"; + } else { + fs = "\"; + } + + // Get the base physical path to the web root for this application. The code to determine the path automatically assumes that + // the "FCKeditor" directory in the http request path is directly off the web root for the application and that it's not a + // virtual directory or a symbolic link / junction. Use the serverPath config setting to force a physical path if necessary. + if ( len(config.serverPath) ) { + serverPath = config.serverPath; + } else { + serverPath = replaceNoCase(getBaseTemplatePath(),replace(cgi.script_name,"/",fs,"all"),""); + } + + // map the user files path to a physical directory + userFilesServerPath = serverPath & replace(userFilesPath,"/",fs,"all"); + + xmlContent = ""; // append to this string to build content + + + + + "> + + + + "> + + + + + + + + + + + + + + + + + + + + + + + + + + + + "> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + errorNumber = 0; + fileName = cffile.ClientFileName; + fileExt = cffile.ServerFileExt; + + // munge filename for html download. Only a-z, 0-9, _, - and . are allowed + if( reFind("[^A-Za-z0-9_\-\.]", fileName) ) { + fileName = reReplace(fileName, "[^A-Za-z0-9\-\.]", "_", "ALL"); + fileName = reReplace(fileName, "_{2,}", "_", "ALL"); + fileName = reReplace(fileName, "([^_]+)_+$", "\1", "ALL"); + fileName = reReplace(fileName, "$_([^_]+)$", "\1", "ALL"); + } + + // When the original filename already exists, add numbers (0), (1), (2), ... at the end of the filename. + if( compare( cffile.ServerFileName, fileName ) ) { + counter = 0; + tmpFileName = fileName; + while( fileExists("#currentFolderPath##fileName#.#fileExt#") ) { + counter = counter + 1; + fileName = tmpFileName & '(#counter#)'; + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + i=1; + folders = ""; + while( i lte qDir.recordCount ) { + if( not compareNoCase( qDir.type[i], "FILE" )) + break; + if( not listFind(".,..", qDir.name[i]) ) + folders = folders & ''; + i=i+1; + } + + xmlContent = xmlContent & '' & folders & ''; + + + + + + + + + + + + i=1; + folders = ""; + files = ""; + while( i lte qDir.recordCount ) { + if( not compareNoCase( qDir.type[i], "DIR" ) and not listFind(".,..", qDir.name[i]) ) { + folders = folders & ''; + } else if( not compareNoCase( qDir.type[i], "FILE" ) ) { + fileSizeKB = round(qDir.size[i] / 1024); + files = files & ''; + } + i=i+1; + } + + xmlContent = xmlContent & '' & folders & ''; + xmlContent = xmlContent & '' & files & ''; + + + + + + + + + + + newFolderName = url.newFolderName; + if( reFind("[^A-Za-z0-9_\-\.]", newFolderName) ) { + // Munge folder name same way as we do the filename + // This means folder names are always US-ASCII so we don't have to worry about CF5 and UTF-8 + newFolderName = reReplace(newFolderName, "[^A-Za-z0-9\-\.]", "_", "all"); + newFolderName = reReplace(newFolderName, "_{2,}", "_", "all"); + newFolderName = reReplace(newFolderName, "([^_]+)_+$", "\1", "all"); + newFolderName = reReplace(newFolderName, "$_([^_]+)$", "\1", "all"); + } + + + + + + + + + + + + + + + + + + + + + '> + + + + + + + + + + + + + + + + + xmlHeader = ''; + xmlHeader = xmlHeader & ''; + xmlFooter = ''; + + + + + + +#xmlHeader##xmlContent##xmlFooter# \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/basexml.pl b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/basexml.pl new file mode 100644 index 00000000..b888f2e5 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/basexml.pl @@ -0,0 +1,59 @@ +##### +# FCKeditor - The text editor for internet +# Copyright (C) 2003-2005 Frederico Caldeira Knabben +# +# Licensed under the terms of the GNU Lesser General Public License: +# http://www.opensource.org/licenses/lgpl-license.php +# +# For further information visit: +# http://www.fckeditor.net/ +# +# "Support Open Source software. What about a donation today?" +# +# File Name: basexml.pl +# This is the File Manager Connector for Perl. +# +# File Authors: +# Takashi Yamaguchi (jack@omakase.net) +##### + +sub CreateXmlHeader +{ + local($command,$resourceType,$currentFolder) = @_; + + # Create the XML document header. + print ''; + + # Create the main "Connector" node. + print ''; + + # Add the current folder node. + print ''; +} + +sub CreateXmlFooter +{ + print ''; +} + +sub SendError +{ + local( $number, $text ) = @_; + + print << "_HTML_HEAD_"; +Content-Type:text/xml; charset=utf-8 +Pragma: no-cache +Cache-Control: no-cache +Expires: Thu, 01 Dec 1994 16:00:00 GMT + +_HTML_HEAD_ + + # Create the XML document header + print '' ; + + print '' ; + + exit ; +} + +1; diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/commands.pl b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/commands.pl new file mode 100644 index 00000000..a8b49a78 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/commands.pl @@ -0,0 +1,154 @@ +##### +# FCKeditor - The text editor for internet +# Copyright (C) 2003-2005 Frederico Caldeira Knabben +# +# Licensed under the terms of the GNU Lesser General Public License: +# http://www.opensource.org/licenses/lgpl-license.php +# +# For further information visit: +# http://www.fckeditor.net/ +# +# "Support Open Source software. What about a donation today?" +# +# File Name: commands.pl +# This is the File Manager Connector for Perl. +# +# File Authors: +# Takashi Yamaguchi (jack@omakase.net) +##### + +sub GetFolders +{ + + local($resourceType, $currentFolder) = @_; + + # Map the virtual path to the local server path. + $sServerDir = &ServerMapFolder($resourceType, $currentFolder); + print ""; # Open the "Folders" node. + + opendir(DIR,"$sServerDir"); + @files = grep(!/^\.\.?$/,readdir(DIR)); + closedir(DIR); + + foreach $sFile (@files) { + if($sFile != '.' && $sFile != '..' && (-d "$sServerDir$sFile")) { + $cnv_filename = &ConvertToXmlAttribute($sFile); + print ''; + } + } + print ""; # Close the "Folders" node. +} + +sub GetFoldersAndFiles +{ + + local($resourceType, $currentFolder) = @_; + # Map the virtual path to the local server path. + $sServerDir = &ServerMapFolder($resourceType,$currentFolder); + + # Initialize the output buffers for "Folders" and "Files". + $sFolders = ''; + $sFiles = ''; + + opendir(DIR,"$sServerDir"); + @files = grep(!/^\.\.?$/,readdir(DIR)); + closedir(DIR); + + foreach $sFile (@files) { + if($sFile ne '.' && $sFile ne '..') { + if(-d "$sServerDir$sFile") { + $cnv_filename = &ConvertToXmlAttribute($sFile); + $sFolders .= '' ; + } else { + ($iFileSize,$refdate,$filedate,$fileperm) = (stat("$sServerDir$sFile"))[7,8,9,2]; + if($iFileSize > 0) { + $iFileSize = int($iFileSize / 1024); + if($iFileSize < 1) { + $iFileSize = 1; + } + } + $cnv_filename = &ConvertToXmlAttribute($sFile); + $sFiles .= '' ; + } + } + } + print $sFolders ; + print ''; # Close the "Folders" node. + print $sFiles ; + print ''; # Close the "Files" node. +} + +sub CreateFolder +{ + + local($resourceType, $currentFolder) = @_; + $sErrorNumber = '0' ; + $sErrorMsg = '' ; + + if($FORM{'NewFolderName'} ne "") { + $sNewFolderName = $FORM{'NewFolderName'}; + # Map the virtual path to the local server path of the current folder. + $sServerDir = &ServerMapFolder($resourceType, $currentFolder); + if(-w $sServerDir) { + $sServerDir .= $sNewFolderName; + $sErrorMsg = &CreateServerFolder($sServerDir); + if($sErrorMsg == 0) { + $sErrorNumber = '0'; + } elsif($sErrorMsg eq 'Invalid argument' || $sErrorMsg eq 'No such file or directory') { + $sErrorNumber = '102'; #// Path too long. + } else { + $sErrorNumber = '110'; + } + } else { + $sErrorNumber = '103'; + } + } else { + $sErrorNumber = '102' ; + } + # Create the "Error" node. + $cnv_errmsg = &ConvertToXmlAttribute($sErrorMsg); + print ''; +} + +sub FileUpload +{ +eval("use File::Copy;"); + + local($resourceType, $currentFolder) = @_; + + $sErrorNumber = '0' ; + $sFileName = '' ; + if($new_fname) { + # Map the virtual path to the local server path. + $sServerDir = &ServerMapFolder($resourceType,$currentFolder); + + # Get the uploaded file name. + $sFileName = $new_fname; + $sOriginalFileName = $sFileName; + + $iCounter = 0; + while(1) { + $sFilePath = $sServerDir . $sFileName; + if(-e $sFilePath) { + $iCounter++ ; + ($path,$BaseName,$ext) = &RemoveExtension($sOriginalFileName); + $sFileName = $BaseName . '(' . $iCounter . ').' . $ext; + $sErrorNumber = '201'; + } else { + copy("$img_dir/$new_fname","$sFilePath"); + chmod(0777,$sFilePath); + unlink("$img_dir/$new_fname"); + last; + } + } + } else { + $sErrorNumber = '202' ; + } + $sFileName =~ s/"/\\"/g; + print "Content-type: text/html\n\n"; + print ''; + exit ; +} +1; diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/connector.cgi b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/connector.cgi new file mode 100644 index 00000000..530cfd26 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/connector.cgi @@ -0,0 +1,134 @@ +#!/usr/bin/env perl + +##### +# FCKeditor - The text editor for internet +# Copyright (C) 2003-2005 Frederico Caldeira Knabben +# +# Licensed under the terms of the GNU Lesser General Public License: +# http://www.opensource.org/licenses/lgpl-license.php +# +# For further information visit: +# http://www.fckeditor.net/ +# +# "Support Open Source software. What about a donation today?" +# +# File Name: connector.cgi +# This is the File Manager Connector for Perl. +# +# File Authors: +# Takashi Yamaguchi (jack@omakase.net) +# Frederico Caldeira Knabben (fredck@fckeditor.net) +##### + +## +# ATTENTION: To enable this connector, look for the "SECURITY" comment in this file. +## + +## START: Hack for Windows (Not important to understand the editor code... Perl specific). +if(Windows_check()) { + chdir(GetScriptPath($0)); +} + +sub Windows_check +{ + # IIS,PWS(NT/95) + $www_server_os = $^O; + # Win98 & NT(SP4) + if($www_server_os eq "") { $www_server_os= $ENV{'OS'}; } + # AnHTTPd/Omni/IIS + if($ENV{'SERVER_SOFTWARE'} =~ /AnWeb|Omni|IIS\//i) { $www_server_os= 'win'; } + # Win Apache + if($ENV{'WINDIR'} ne "") { $www_server_os= 'win'; } + if($www_server_os=~ /win/i) { return(1); } + return(0); +} + +sub GetScriptPath { + local($path) = @_; + if($path =~ /[\:\/\\]/) { $path =~ s/(.*?)[\/\\][^\/\\]+$/$1/; } else { $path = '.'; } + $path; +} +## END: Hack for IIS + +require 'util.pl'; +require 'io.pl'; +require 'basexml.pl'; +require 'commands.pl'; +require 'upload_fck.pl'; + +## +# SECURITY: REMOVE/COMMENT THE FOLLOWING LINE TO ENABLE THIS CONNECTOR. +## +&SendError( 1, 'This connector is disabled. Please check the "editor/filemanager/browser/default/connectors/perl/connector.cgi" file' ) ; + + &read_input(); + + if($FORM{'ServerPath'} ne "") { + $GLOBALS{'UserFilesPath'} = $FORM{'ServerPath'}; + if(!($GLOBALS{'UserFilesPath'} =~ /\/$/)) { + $GLOBALS{'UserFilesPath'} .= '/' ; + } + } else { + $GLOBALS{'UserFilesPath'} = '/UserFiles/'; + } + + # Map the "UserFiles" path to a local directory. + $rootpath = &GetRootPath(); + $GLOBALS{'UserFilesDirectory'} = $rootpath . $GLOBALS{'UserFilesPath'}; + + &DoResponse(); + +sub DoResponse +{ + + if($FORM{'Command'} eq "" || $FORM{'Type'} eq "" || $FORM{'CurrentFolder'} eq "") { + return ; + } + # Get the main request informaiton. + $sCommand = $FORM{'Command'}; + $sResourceType = $FORM{'Type'}; + $sCurrentFolder = $FORM{'CurrentFolder'}; + + # Check the current folder syntax (must begin and start with a slash). + if(!($sCurrentFolder =~ /\/$/)) { + $sCurrentFolder .= '/'; + } + if(!($sCurrentFolder =~ /^\//)) { + $sCurrentFolder = '/' . $sCurrentFolder; + } + + # Check for invalid folder paths (..) + if ( $sCurrentFolder =~ /\.\./ ) { + SendError( 102, "" ) ; + } + + # File Upload doesn't have to Return XML, so it must be intercepted before anything. + if($sCommand eq 'FileUpload') { + FileUpload($sResourceType,$sCurrentFolder); + return ; + } + + print << "_HTML_HEAD_"; +Content-Type:text/xml; charset=utf-8 +Pragma: no-cache +Cache-Control: no-cache +Expires: Thu, 01 Dec 1994 16:00:00 GMT + +_HTML_HEAD_ + + &CreateXmlHeader($sCommand,$sResourceType,$sCurrentFolder); + + # Execute the required command. + if($sCommand eq 'GetFolders') { + &GetFolders($sResourceType,$sCurrentFolder); + } elsif($sCommand eq 'GetFoldersAndFiles') { + &GetFoldersAndFiles($sResourceType,$sCurrentFolder); + } elsif($sCommand eq 'CreateFolder') { + &CreateFolder($sResourceType,$sCurrentFolder); + } + + &CreateXmlFooter(); + + exit ; +} + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/io.pl b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/io.pl new file mode 100644 index 00000000..63557ce3 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/io.pl @@ -0,0 +1,127 @@ +##### +# FCKeditor - The text editor for internet +# Copyright (C) 2003-2005 Frederico Caldeira Knabben +# +# Licensed under the terms of the GNU Lesser General Public License: +# http://www.opensource.org/licenses/lgpl-license.php +# +# For further information visit: +# http://www.fckeditor.net/ +# +# "Support Open Source software. What about a donation today?" +# +# File Name: io.pl +# This is the File Manager Connector for Perl. +# +# File Authors: +# Takashi Yamaguchi (jack@omakase.net) +##### + +sub GetUrlFromPath +{ + local($resourceType, $folderPath) = @_; + + if($resourceType eq '') { + $rmpath = &RemoveFromEnd($GLOBALS{'UserFilesPath'},'/'); + return("$rmpath$folderPath"); + } else { + return("$GLOBALS{'UserFilesPath'}$resourceType$folderPath"); + } +} + +sub RemoveExtension +{ + local($fileName) = @_; + local($path, $base, $ext); + if($fileName !~ /\./) { + $fileName .= '.'; + } + if($fileName =~ /([^\\\/]*)\.(.*)$/) { + $base = $1; + $ext = $2; + if($fileName =~ /(.*)$base\.$ext$/) { + $path = $1; + } + } + return($path,$base,$ext); + +} + +sub ServerMapFolder +{ + local($resourceType,$folderPath) = @_; + + # Get the resource type directory. + $sResourceTypePath = $GLOBALS{'UserFilesDirectory'} . $resourceType . '/'; + + # Ensure that the directory exists. + &CreateServerFolder($sResourceTypePath); + + # Return the resource type directory combined with the required path. + $rmpath = &RemoveFromStart($folderPath,'/'); + return("$sResourceTypePath$rmpath"); +} + +sub GetParentFolder +{ + local($folderPath) = @_; + + $folderPath =~ s/[\/][^\/]+[\/]?$//g; + return $folderPath; +} + +sub CreateServerFolder +{ + local($folderPath) = @_; + + $sParent = &GetParentFolder($folderPath); + # Check if the parent exists, or create it. + if(!(-e $sParent)) { + $sErrorMsg = &CreateServerFolder($sParent); + if($sErrorMsg == 1) { + return(1); + } + } + if(!(-e $folderPath)) { + umask(000); + mkdir("$folderPath",0777); + chmod(0777,"$folderPath"); + return(0); + } else { + return(1); + } +} + +sub GetRootPath +{ +#use Cwd; + +# my $dir = getcwd; +# print $dir; +# $dir =~ s/$ENV{'DOCUMENT_ROOT'}//g; +# print $dir; +# return($dir); + +# $wk = $0; +# $wk =~ s/\/connector\.cgi//g; +# if($wk) { +# $current_dir = $wk; +# } else { +# $current_dir = `pwd`; +# } +# return($current_dir); +use Cwd; + + if($ENV{'DOCUMENT_ROOT'}) { + $dir = $ENV{'DOCUMENT_ROOT'}; + } else { + my $dir = getcwd; + $workdir =~ s/\/connector\.cgi//g; + $dir =~ s/$workdir//g; + } + return($dir); + + + +} +1; diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/upload_fck.pl b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/upload_fck.pl new file mode 100644 index 00000000..21f34a0f --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/upload_fck.pl @@ -0,0 +1,663 @@ +##### +# FCKeditor - The text editor for internet +# Copyright (C) 2003-2005 Frederico Caldeira Knabben +# +# Licensed under the terms of the GNU Lesser General Public License: +# http://www.opensource.org/licenses/lgpl-license.php +# +# For further information visit: +# http://www.fckeditor.net/ +# +# "Support Open Source software. What about a donation today?" +# +# File Name: upload_fck.pl +# This is the File Manager Connector for Perl. +# +# File Authors: +# Takashi Yamaguchi (jack@omakase.net) +##### + +# image data save dir +$img_dir = './temp/'; + + +# File size max(unit KB) +$MAX_CONTENT_SIZE = 30000; + +# Filelock (1=use,0=not use) +$PM{'flock'} = '1'; + + +# upload Content-Type list +my %UPLOAD_CONTENT_TYPE_LIST = ( + 'image/(x-)?png' => 'png', # PNG image + 'image/p?jpe?g' => 'jpg', # JPEG image + 'image/gif' => 'gif', # GIF image + 'image/x-xbitmap' => 'xbm', # XBM image + + 'image/(x-(MS-)?)?bmp' => 'bmp', # Windows BMP image + 'image/pict' => 'pict', # Macintosh PICT image + 'image/tiff' => 'tif', # TIFF image + 'application/pdf' => 'pdf', # PDF image + 'application/x-shockwave-flash' => 'swf', # Shockwave Flash + + 'video/(x-)?msvideo' => 'avi', # Microsoft Video + 'video/quicktime' => 'mov', # QuickTime Video + 'video/mpeg' => 'mpeg', # MPEG Video + 'video/x-mpeg2' => 'mpv2', # MPEG2 Video + + 'audio/(x-)?midi?' => 'mid', # MIDI Audio + 'audio/(x-)?wav' => 'wav', # WAV Audio + 'audio/basic' => 'au', # ULAW Audio + 'audio/mpeg' => 'mpga', # MPEG Audio + + 'application/(x-)?zip(-compressed)?' => 'zip', # ZIP Compress + + 'text/html' => 'html', # HTML + 'text/plain' => 'txt', # TEXT + '(?:application|text)/(?:rtf|richtext)' => 'rtf', # RichText + + 'application/msword' => 'doc', # Microsoft Word + 'application/vnd.ms-excel' => 'xls', # Microsoft Excel + + '' +); + +# Upload is permitted. +# A regular expression is possible. +my %UPLOAD_EXT_LIST = ( + 'png' => 'PNG image', + 'p?jpe?g|jpe|jfif|pjp' => 'JPEG image', + 'gif' => 'GIF image', + 'xbm' => 'XBM image', + + 'bmp|dib|rle' => 'Windows BMP image', + 'pi?ct' => 'Macintosh PICT image', + 'tiff?' => 'TIFF image', + 'pdf' => 'PDF image', + 'swf' => 'Shockwave Flash', + + 'avi' => 'Microsoft Video', + 'moo?v|qt' => 'QuickTime Video', + 'm(p(e?gv?|e|v)|1v)' => 'MPEG Video', + 'mp(v2|2v)' => 'MPEG2 Video', + + 'midi?|kar|smf|rmi|mff' => 'MIDI Audio', + 'wav' => 'WAVE Audio', + 'au|snd' => 'ULAW Audio', + 'mp(e?ga|2|a|3)|abs' => 'MPEG Audio', + + 'zip' => 'ZIP Compress', + 'lzh' => 'LZH Compress', + 'cab' => 'CAB Compress', + + 'd?html?' => 'HTML', + 'rtf|rtx' => 'RichText', + 'txt|text' => 'Text', + + '' +); + + +# sjis or euc +my $CHARCODE = 'sjis'; + +$TRANS_2BYTE_CODE = 0; + +############################################################################## +# Summary +# +# Form Read input +# +# Parameters +# Returns +# Memo +############################################################################## +sub read_input +{ +eval("use File::Copy;"); +eval("use File::Path;"); + + my ($FORM) = @_; + + + mkdir($img_dir,0777); + chmod(0777,$img_dir); + + undef $img_data_exists; + undef @NEWFNAMES; + undef @NEWFNAME_DATA; + + if($ENV{'CONTENT_LENGTH'} > 10000000 || $ENV{'CONTENT_LENGTH'} > $MAX_CONTENT_SIZE * 1024) { + &upload_error( + 'Size Error', + sprintf( + "Transmitting size is too large.MAX %d KB Now Size %d KB(%d bytes Over)", + $MAX_CONTENT_SIZE, + int($ENV{'CONTENT_LENGTH'} / 1024), + $ENV{'CONTENT_LENGTH'} - $MAX_CONTENT_SIZE * 1024 + ) + ); + } + + my $Buffer; + if($ENV{'CONTENT_TYPE'} =~ /multipart\/form-data/) { + # METHOD POST only + return unless($ENV{'CONTENT_LENGTH'}); + + binmode(STDIN); + # STDIN A pause character is detected.'(MacIE3.0 boundary of $ENV{'CONTENT_TYPE'} cannot be trusted.) + my $Boundary = ; + $Boundary =~ s/\x0D\x0A//; + $Boundary = quotemeta($Boundary); + while() { + if(/^\s*Content-Disposition:/i) { + my($name,$ContentType,$FileName); + # form data get + if(/\bname="([^"]+)"/i || /\bname=([^\s:;]+)/i) { + $name = $1; + $name =~ tr/+/ /; + $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; + &Encode(\$name); + } + if(/\bfilename="([^"]*)"/i || /\bfilename=([^\s:;]*)/i) { + $FileName = $1 || 'unknown'; + } + # head read + while() { + last if(! /\w/); + if(/^\s*Content-Type:\s*"([^"]+)"/i || /^\s*Content-Type:\s*([^\s:;]+)/i) { + $ContentType = $1; + } + } + # body read + $value = ""; + while() { + last if(/^$Boundary/o); + $value .= $_; + }; + $lastline = $_; + $value =~s /\x0D\x0A$//; + if($value ne '') { + if($FileName || $ContentType) { + $img_data_exists = 1; + ( + $FileName, # + $Ext, # + $Length, # + $ImageWidth, # + $ImageHeight, # + $ContentName # + ) = &CheckContentType(\$value,$FileName,$ContentType); + + $FORM{$name} = $FileName; + $new_fname = $FileName; + push(@NEWFNAME_DATA,"$FileName\t$Ext\t$Length\t$ImageWidth\t$ImageHeight\t$ContentName"); + + # Multi-upload correspondence + push(@NEWFNAMES,$new_fname); + open(OUT,">$img_dir/$new_fname"); + binmode(OUT); + eval "flock(OUT,2);" if($PM{'flock'} == 1); + print OUT $value; + eval "flock(OUT,8);" if($PM{'flock'} == 1); + close(OUT); + + } elsif($name) { + $value =~ tr/+/ /; + $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; + &Encode(\$value,'trans'); + $FORM{$name} .= "\0" if(defined($FORM{$name})); + $FORM{$name} .= $value; + } + } + }; + last if($lastline =~ /^$Boundary\-\-/o); + } + } elsif($ENV{'CONTENT_LENGTH'}) { + read(STDIN,$Buffer,$ENV{'CONTENT_LENGTH'}); + } + foreach(split(/&/,$Buffer),split(/&/,$ENV{'QUERY_STRING'})) { + my($name, $value) = split(/=/); + $name =~ tr/+/ /; + $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; + $value =~ tr/+/ /; + $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; + + &Encode(\$name); + &Encode(\$value,'trans'); + $FORM{$name} .= "\0" if(defined($FORM{$name})); + $FORM{$name} .= $value; + + } + +} + +############################################################################## +# Summary +# +# CheckContentType +# +# Parameters +# Returns +# Memo +############################################################################## +sub CheckContentType +{ + + my($DATA,$FileName,$ContentType) = @_; + my($Ext,$ImageWidth,$ImageHeight,$ContentName,$Infomation); + my $DataLength = length($$DATA); + + # An unknown file type + + $_ = $ContentType; + my $UnknownType = ( + !$_ + || /^application\/(x-)?macbinary$/i + || /^application\/applefile$/i + || /^application\/octet-stream$/i + || /^text\/plane$/i + || /^x-unknown-content-type/i + ); + + # MacBinary(Mac Unnecessary data are deleted.) + if($UnknownType || $ENV{'HTTP_USER_AGENT'} =~ /Macintosh|Mac_/) { + if($DataLength > 128 && !unpack("C",substr($$DATA,0,1)) && !unpack("C",substr($$DATA,74,1)) && !unpack("C",substr($$DATA,82,1)) ) { + my $MacBinary_ForkLength = unpack("N", substr($$DATA, 83, 4)); # ForkLength Get + my $MacBinary_FileName = quotemeta(substr($$DATA, 2, unpack("C",substr($$DATA, 1, 1)))); + if($MacBinary_FileName && $MacBinary_ForkLength && $DataLength >= $MacBinary_ForkLength + 128 + && ($FileName =~ /$MacBinary_FileName/i || substr($$DATA,102,4) eq 'mBIN')) { # DATA TOP 128byte MacBinary!! + $$DATA = substr($$DATA,128,$MacBinary_ForkLength); + my $ResourceLength = $DataLength - $MacBinary_ForkLength - 128; + $DataLength = $MacBinary_ForkLength; + } + } + } + + # A file name is changed into EUC. +# &jcode::convert(\$FileName,'euc',$FormCodeDefault); +# &jcode::h2z_euc(\$FileName); + $FileName =~ s/^.*\\//; # Windows, Mac + $FileName =~ s/^.*\///; # UNIX + $FileName =~ s/&/&/g; + $FileName =~ s/"/"/g; + $FileName =~ s//>/g; +# +# if($CHARCODE ne 'euc') { +# &jcode::convert(\$FileName,$CHARCODE,'euc'); +# } + + # An extension is extracted and it changes into a small letter. + my $FileExt; + if($FileName =~ /\.(\w+)$/) { + $FileExt = $1; + $FileExt =~ tr/A-Z/a-z/; + } + + # Executable file detection (ban on upload) + if($$DATA =~ /^MZ/) { + $Ext = 'exe'; + } + # text + if(!$Ext && ($UnknownType || $ContentType =~ /^text\//i || $ContentType =~ /^application\/(?:rtf|richtext)$/i || $ContentType =~ /^image\/x-xbitmap$/i) + && ! $$DATA =~ /[\000-\006\177\377]/) { +# $$DATA =~ s/\x0D\x0A/\n/g; +# $$DATA =~ tr/\x0D\x0A/\n\n/; +# +# if( +# $$DATA =~ /<\s*SCRIPT(?:.|\n)*?>/i +# || $$DATA =~ /<\s*(?:.|\n)*?\bONLOAD\s*=(?:.|\n)*?>/i +# || $$DATA =~ /<\s*(?:.|\n)*?\bONCLICK\s*=(?:.|\n)*?>/i +# ) { +# $Infomation = '(JavaScript contains)'; +# } +# if($$DATA =~ /<\s*TABLE(?:.|\n)*?>/i +# || $$DATA =~ /<\s*BLINK(?:.|\n)*?>/i +# || $$DATA =~ /<\s*MARQUEE(?:.|\n)*?>/i +# || $$DATA =~ /<\s*OBJECT(?:.|\n)*?>/i +# || $$DATA =~ /<\s*EMBED(?:.|\n)*?>/i +# || $$DATA =~ /<\s*FRAME(?:.|\n)*?>/i +# || $$DATA =~ /<\s*APPLET(?:.|\n)*?>/i +# || $$DATA =~ /<\s*FORM(?:.|\n)*?>/i +# || $$DATA =~ /<\s*(?:.|\n)*?\bSRC\s*=(?:.|\n)*?>/i +# || $$DATA =~ /<\s*(?:.|\n)*?\bDYNSRC\s*=(?:.|\n)*?>/i +# ) { +# $Infomation = '(the HTML tag which is not safe is included)'; +# } + + if($FileExt =~ /^txt$/i || $FileExt =~ /^cgi$/i || $FileExt =~ /^pl$/i) { # Text File + $Ext = 'txt'; + } elsif($ContentType =~ /^text\/html$/i || $FileExt =~ /html?/i || $$DATA =~ /<\s*HTML(?:.|\n)*?>/i) { # HTML File + $Ext = 'html'; + } elsif($ContentType =~ /^image\/x-xbitmap$/i || $FileExt =~ /^xbm$/i) { # XBM(x-BitMap) Image + my $XbmName = $1; + my ($XbmWidth, $XbmHeight); + if($$DATA =~ /\#define\s*$XbmName\_width\s*(\d+)/i) { + $XbmWidth = $1; + } + if($$DATA =~ /\#define\s*$XbmName\_height\s*(\d+)/i) { + $XbmHeight = $1; + } + if($XbmWidth && $XbmHeight) { + $Ext = 'xbm'; + $ImageWidth = $XbmWidth; + $ImageHeight = $XbmHeight; + } + } else { # + $Ext = 'txt'; + } + } + + # image + if(!$Ext && ($UnknownType || $ContentType =~ /^image\//i)) { + # PNG + if($$DATA =~ /^\x89PNG\x0D\x0A\x1A\x0A/) { + if(substr($$DATA, 12, 4) eq 'IHDR') { + $Ext = 'png'; + ($ImageWidth, $ImageHeight) = unpack("N2", substr($$DATA, 16, 8)); + } + } elsif($$DATA =~ /^GIF8(?:9|7)a/) { # GIF89a(modified), GIF89a, GIF87a + $Ext = 'gif'; + ($ImageWidth, $ImageHeight) = unpack("v2", substr($$DATA, 6, 4)); + } elsif($$DATA =~ /^II\x2a\x00\x08\x00\x00\x00/ || $$DATA =~ /^MM\x00\x2a\x00\x00\x00\x08/) { # TIFF + $Ext = 'tif'; + } elsif($$DATA =~ /^BM/) { # BMP + $Ext = 'bmp'; + } elsif($$DATA =~ /^\xFF\xD8\xFF/ || $$DATA =~ /JFIF/) { # JPEG + my $HeaderPoint = index($$DATA, "\xFF\xD8\xFF", 0); + my $Point = $HeaderPoint + 2; + while($Point < $DataLength) { + my($Maker, $MakerType, $MakerLength) = unpack("C2n",substr($$DATA,$Point,4)); + if($Maker != 0xFF || $MakerType == 0xd9 || $MakerType == 0xda) { + last; + } elsif($MakerType >= 0xC0 && $MakerType <= 0xC3) { + $Ext = 'jpg'; + ($ImageHeight, $ImageWidth) = unpack("n2", substr($$DATA, $Point + 5, 4)); + if($HeaderPoint > 0) { + $$DATA = substr($$DATA, $HeaderPoint); + $DataLength = length($$DATA); + } + last; + } else { + $Point += $MakerLength + 2; + } + } + } + } + + # audio + if(!$Ext && ($UnknownType || $ContentType =~ /^audio\//i)) { + # MIDI Audio + if($$DATA =~ /^MThd/) { + $Ext = 'mid'; + } elsif($$DATA =~ /^\x2esnd/) { # ULAW Audio + $Ext = 'au'; + } elsif($$DATA =~ /^RIFF/ || $$DATA =~ /^ID3/ && $$DATA =~ /RIFF/) { + my $HeaderPoint = index($$DATA, "RIFF", 0); + $_ = substr($$DATA, $HeaderPoint + 8, 8); + if(/^WAVEfmt $/) { + # WAVE + if(unpack("V",substr($$DATA, $HeaderPoint + 16, 4)) == 16) { + $Ext = 'wav'; + } else { # RIFF WAVE MP3 + $Ext = 'mp3'; + } + } elsif(/^RMIDdata$/) { # RIFF MIDI + $Ext = 'rmi'; + } elsif(/^RMP3data$/) { # RIFF MP3 + $Ext = 'rmp'; + } + if($ContentType =~ /^audio\//i) { + $Infomation .= '(RIFF '. substr($$DATA, $HeaderPoint + 8, 4). ')'; + } + } + } + + # a binary file + unless ($Ext) { + # PDF image + if($$DATA =~ /^\%PDF/) { + # Picture size is not measured. + $Ext = 'pdf'; + } elsif($$DATA =~ /^FWS/) { # Shockwave Flash + $Ext = 'swf'; + } elsif($$DATA =~ /^RIFF/ || $$DATA =~ /^ID3/ && $$DATA =~ /RIFF/) { + my $HeaderPoint = index($$DATA, "RIFF", 0); + $_ = substr($$DATA,$HeaderPoint + 8, 8); + # AVI + if(/^AVI LIST$/) { + $Ext = 'avi'; + } + if($ContentType =~ /^video\//i) { + $Infomation .= '(RIFF '. substr($$DATA, $HeaderPoint + 8, 4). ')'; + } + } elsif($$DATA =~ /^PK/) { # ZIP Compress File + $Ext = 'zip'; + } elsif($$DATA =~ /^MSCF/) { # CAB Compress File + $Ext = 'cab'; + } elsif($$DATA =~ /^Rar\!/) { # RAR Compress File + $Ext = 'rar'; + } elsif(substr($$DATA, 2, 5) =~ /^\-lh(\d+|d)\-$/) { # LHA Compress File + $Infomation .= "(lh$1)"; + $Ext = 'lzh'; + } elsif(substr($$DATA, 325, 25) eq "Apple Video Media Handler" || substr($$DATA, 325, 30) eq "Apple \x83\x72\x83\x66\x83\x49\x81\x45\x83\x81\x83\x66\x83\x42\x83\x41\x83\x6E\x83\x93\x83\x68\x83\x89") { + # QuickTime + $Ext = 'mov'; + } + } + + # Header analysis failure + unless ($Ext) { + # It will be followed if it applies for the MIME type from the browser. + foreach (keys %UPLOAD_CONTENT_TYPE_LIST) { + next unless ($_); + if($ContentType =~ /^$_$/i) { + $Ext = $UPLOAD_CONTENT_TYPE_LIST{$_}; + $ContentName = &CheckContentExt($Ext); + if( + grep {$_ eq $Ext;} ( + 'png', + 'gif', + 'jpg', + 'xbm', + 'tif', + 'bmp', + 'pdf', + 'swf', + 'mov', + 'zip', + 'cab', + 'lzh', + 'rar', + 'mid', + 'rmi', + 'au', + 'wav', + 'avi', + 'exe' + ) + ) { + $Infomation .= ' / Header analysis failure'; + } + if($Ext ne $FileExt && &CheckContentExt($FileExt) eq $ContentName) { + $Ext = $FileExt; + } + last; + } + } + # a MIME type is unknown--It judges from an extension. + unless ($Ext) { + $ContentName = &CheckContentExt($FileExt); + if($ContentName) { + $Ext = $FileExt; + $Infomation .= ' / MIME type is unknown('. $ContentType. ')'; + last; + } + } + } + +# $ContentName = &CheckContentExt($Ext) unless($ContentName); +# if($Ext && $ContentName) { +# $ContentName .= $Infomation; +# } else { +# &upload_error( +# 'Extension Error', +# "$FileName A not corresponding extension ($Ext)
The extension which can be responded ". join(',', sort values(%UPLOAD_EXT_LIST)) +# ); +# } + +# # SSI Tag Deletion +# if($Ext =~ /.?html?/ && $$DATA =~ /<\!/) { +# foreach ( +# 'config', +# 'echo', +# 'exec', +# 'flastmod', +# 'fsize', +# 'include' +# ) { +# $$DATA =~ s/\#\s*$_/\&\#35\;$_/ig +# } +# } + + return ( + $FileName, + $Ext, + int($DataLength / 1024 + 1), + $ImageWidth, + $ImageHeight, + $ContentName + ); +} + +############################################################################## +# Summary +# +# Extension discernment +# +# Parameters +# Returns +# Memo +############################################################################## + +sub CheckContentExt +{ + + my($Ext) = @_; + my $ContentName; + foreach (keys %UPLOAD_EXT_LIST) { + next unless ($_); + if($_ && $Ext =~ /^$_$/) { + $ContentName = $UPLOAD_EXT_LIST{$_}; + last; + } + } + return $ContentName; + +} + +############################################################################## +# Summary +# +# Form decode +# +# Parameters +# Returns +# Memo +############################################################################## +sub Encode +{ + + my($value,$Trans) = @_; + +# my $FormCode = &jcode::getcode($value) || $FormCodeDefault; +# $FormCodeDefault ||= $FormCode; +# +# if($Trans && $TRANS_2BYTE_CODE) { +# if($FormCode ne 'euc') { +# &jcode::convert($value, 'euc', $FormCode); +# } +# &jcode::tr( +# $value, +# "\xA3\xB0-\xA3\xB9\xA3\xC1-\xA3\xDA\xA3\xE1-\xA3\xFA", +# '0-9A-Za-z' +# ); +# if($CHARCODE ne 'euc') { +# &jcode::convert($value,$CHARCODE,'euc'); +# } +# } else { +# if($CHARCODE ne $FormCode) { +# &jcode::convert($value,$CHARCODE,$FormCode); +# } +# } +# if($CHARCODE eq 'euc') { +# &jcode::h2z_euc($value); +# } elsif($CHARCODE eq 'sjis') { +# &jcode::h2z_sjis($value); +# } + +} + +############################################################################## +# Summary +# +# Error Msg +# +# Parameters +# Returns +# Memo +############################################################################## + +sub upload_error +{ + + local($error_message) = $_[0]; + local($error_message2) = $_[1]; + + print "Content-type: text/html\n\n"; + print< + +Error Message + + + + + +
Error Message
+
    +

    $error_message

    +$error_message2
    +
+ + +EOF + &rm_tmp_uploaded_files; # Image Temporary deletion + exit; +} + +############################################################################## +# Summary +# +# Image Temporary deletion +# +# Parameters +# Returns +# Memo +############################################################################## + +sub rm_tmp_uploaded_files +{ + if($img_data_exists == 1){ + sleep 1; + foreach $fname_list(@NEWFNAMES) { + if(-e "$img_dir/$fname_list") { + unlink("$img_dir/$fname_list"); + } + } + } + +} +1; diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/util.pl b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/util.pl new file mode 100644 index 00000000..287de4f9 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/perl/util.pl @@ -0,0 +1,56 @@ +##### +# FCKeditor - The text editor for internet +# Copyright (C) 2003-2005 Frederico Caldeira Knabben +# +# Licensed under the terms of the GNU Lesser General Public License: +# http://www.opensource.org/licenses/lgpl-license.php +# +# For further information visit: +# http://www.fckeditor.net/ +# +# "Support Open Source software. What about a donation today?" +# +# File Name: util.pl +# This is the File Manager Connector for Perl. +# +# File Authors: +# Takashi Yamaguchi (jack@omakase.net) +##### + +sub RemoveFromStart +{ + local($sourceString, $charToRemove) = @_; + $sPattern = '^' . $charToRemove . '+' ; + $sourceString =~ s/^$charToRemove+//g; + return $sourceString; +} + +sub RemoveFromEnd +{ + local($sourceString, $charToRemove) = @_; + $sPattern = $charToRemove . '+$' ; + $sourceString =~ s/$charToRemove+$//g; + return $sourceString; +} + +sub ConvertToXmlAttribute +{ + local($value) = @_; + return $value; +# return utf8_encode(htmlspecialchars($value)); + +} + +sub specialchar_cnv +{ + local($ch) = @_; + + $ch =~ s/&/&/g; # & + $ch =~ s/\"/"/g; #" + $ch =~ s/\'/'/g; # ' + $ch =~ s//>/g; # > + return($ch); +} + +1; diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/basexml.php b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/basexml.php new file mode 100644 index 00000000..b21b16c2 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/basexml.php @@ -0,0 +1,68 @@ +' ; + + // Create the main "Connector" node. + echo '' ; + + // Add the current folder node. + echo '' ; +} + +function CreateXmlFooter() +{ + echo '' ; +} + +function SendError( $number, $text ) +{ + SetXmlHeaders() ; + + // Create the XML document header + echo '' ; + + echo '' ; + + exit ; +} +?> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/commands.php b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/commands.php new file mode 100644 index 00000000..a3f5e41b --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/commands.php @@ -0,0 +1,211 @@ +' ; + } + + closedir( $oCurrentFolder ) ; + + // Open the "Folders" node. + echo "" ; + + natcasesort( $aFolders ) ; + foreach ( $aFolders as $sFolder ) + echo $sFolder ; + + // Close the "Folders" node. + echo "" ; +} + +function GetFoldersAndFiles( $resourceType, $currentFolder ) +{ + // Map the virtual path to the local server path. + $sServerDir = ServerMapFolder( $resourceType, $currentFolder ) ; + + // Arrays that will hold the folders and files names. + $aFolders = array() ; + $aFiles = array() ; + + $oCurrentFolder = opendir( $sServerDir ) ; + + while ( $sFile = readdir( $oCurrentFolder ) ) + { + if ( $sFile != '.' && $sFile != '..' ) + { + if ( is_dir( $sServerDir . $sFile ) ) + $aFolders[] = '' ; + else + { + $iFileSize = filesize( $sServerDir . $sFile ) ; + if ( $iFileSize > 0 ) + { + $iFileSize = round( $iFileSize / 1024 ) ; + if ( $iFileSize < 1 ) $iFileSize = 1 ; + } + + $aFiles[] = '' ; + } + } + } + + // Send the folders + natcasesort( $aFolders ) ; + echo '' ; + + foreach ( $aFolders as $sFolder ) + echo $sFolder ; + + echo '' ; + + // Send the files + natcasesort( $aFiles ) ; + echo '' ; + + foreach ( $aFiles as $sFiles ) + echo $sFiles ; + + echo '' ; +} + +function CreateFolder( $resourceType, $currentFolder ) +{ + $sErrorNumber = '0' ; + $sErrorMsg = '' ; + + if ( isset( $_GET['NewFolderName'] ) ) + { + $sNewFolderName = $_GET['NewFolderName'] ; + + if ( strpos( $sNewFolderName, '..' ) !== FALSE ) + $sErrorNumber = '102' ; // Invalid folder name. + else + { + // Map the virtual path to the local server path of the current folder. + $sServerDir = ServerMapFolder( $resourceType, $currentFolder ) ; + + if ( is_writable( $sServerDir ) ) + { + $sServerDir .= $sNewFolderName ; + + $sErrorMsg = CreateServerFolder( $sServerDir ) ; + + switch ( $sErrorMsg ) + { + case '' : + $sErrorNumber = '0' ; + break ; + case 'Invalid argument' : + case 'No such file or directory' : + $sErrorNumber = '102' ; // Path too long. + break ; + default : + $sErrorNumber = '110' ; + break ; + } + } + else + $sErrorNumber = '103' ; + } + } + else + $sErrorNumber = '102' ; + + // Create the "Error" node. + echo '' ; +} + +function FileUpload( $resourceType, $currentFolder ) +{ + $sErrorNumber = '0' ; + $sFileName = '' ; + + if ( isset( $_FILES['NewFile'] ) && !is_null( $_FILES['NewFile']['tmp_name'] ) ) + { + $oFile = $_FILES['NewFile'] ; + + // Map the virtual path to the local server path. + $sServerDir = ServerMapFolder( $resourceType, $currentFolder ) ; + + // Get the uploaded file name. + $sFileName = $oFile['name'] ; + $sOriginalFileName = $sFileName ; + $sExtension = substr( $sFileName, ( strrpos($sFileName, '.') + 1 ) ) ; + $sExtension = strtolower( $sExtension ) ; + + global $Config ; + + $arAllowed = $Config['AllowedExtensions'][$resourceType] ; + $arDenied = $Config['DeniedExtensions'][$resourceType] ; + + if ( ( count($arAllowed) == 0 || in_array( $sExtension, $arAllowed ) ) && ( count($arDenied) == 0 || !in_array( $sExtension, $arDenied ) ) ) + { + $iCounter = 0 ; + + while ( true ) + { + $sFilePath = $sServerDir . $sFileName ; + + if ( is_file( $sFilePath ) ) + { + $iCounter++ ; + $sFileName = RemoveExtension( $sOriginalFileName ) . '(' . $iCounter . ').' . $sExtension ; + $sErrorNumber = '201' ; + } + else + { + move_uploaded_file( $oFile['tmp_name'], $sFilePath ) ; + + if ( is_file( $sFilePath ) ) + { + $oldumask = umask(0) ; + chmod( $sFilePath, 0777 ) ; + umask( $oldumask ) ; + } + + break ; + } + } + } + else + $sErrorNumber = '202' ; + } + else + $sErrorNumber = '202' ; + + echo '' ; + + exit ; +} +?> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/config.php b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/config.php new file mode 100644 index 00000000..4c45b7cc --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/config.php @@ -0,0 +1,47 @@ + \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php new file mode 100644 index 00000000..255a459f --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php @@ -0,0 +1,107 @@ + 0 ) +{ + $GLOBALS["UserFilesDirectory"] = $Config['UserFilesAbsolutePath'] ; + + if ( ! ereg( '/$', $GLOBALS["UserFilesDirectory"] ) ) + $GLOBALS["UserFilesDirectory"] .= '/' ; +} +else +{ + // Map the "UserFiles" path to a local directory. + $GLOBALS["UserFilesDirectory"] = GetRootPath() . $GLOBALS["UserFilesPath"] ; +} + +DoResponse() ; + +function DoResponse() +{ + if ( !isset( $_GET['Command'] ) || !isset( $_GET['Type'] ) || !isset( $_GET['CurrentFolder'] ) ) + return ; + + // Get the main request informaiton. + $sCommand = $_GET['Command'] ; + $sResourceType = $_GET['Type'] ; + $sCurrentFolder = $_GET['CurrentFolder'] ; + + // Check if it is an allowed type. + if ( !in_array( $sResourceType, array('File','Image','Flash','Media') ) ) + return ; + + // Check the current folder syntax (must begin and start with a slash). + if ( ! ereg( '/$', $sCurrentFolder ) ) $sCurrentFolder .= '/' ; + if ( strpos( $sCurrentFolder, '/' ) !== 0 ) $sCurrentFolder = '/' . $sCurrentFolder ; + + // Check for invalid folder paths (..) + if ( strpos( $sCurrentFolder, '..' ) ) + SendError( 102, "" ) ; + + // File Upload doesn't have to Return XML, so it must be intercepted before anything. + if ( $sCommand == 'FileUpload' ) + { + FileUpload( $sResourceType, $sCurrentFolder ) ; + return ; + } + + CreateXmlHeader( $sCommand, $sResourceType, $sCurrentFolder ) ; + + // Execute the required command. + switch ( $sCommand ) + { + case 'GetFolders' : + GetFolders( $sResourceType, $sCurrentFolder ) ; + break ; + case 'GetFoldersAndFiles' : + GetFoldersAndFiles( $sResourceType, $sCurrentFolder ) ; + break ; + case 'CreateFolder' : + CreateFolder( $sResourceType, $sCurrentFolder ) ; + break ; + } + + CreateXmlFooter() ; + + exit ; +} +?> \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/io.php b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/io.php new file mode 100644 index 00000000..f4fb51f8 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/io.php @@ -0,0 +1,97 @@ + \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/util.php b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/util.php new file mode 100644 index 00000000..8b87fcbe --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/php/util.php @@ -0,0 +1,37 @@ + \ No newline at end of file diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/test.html b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/test.html new file mode 100644 index 00000000..609f59de --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/connectors/test.html @@ -0,0 +1,168 @@ + + + + + FCKeditor - Connectors Tests + + + + + + + + + + +
+ + + + + + + + + + +
Connector:
+
   Current Folder
+
   Resource Type
+
   Server Path
+
+
+ + + + + + + + + + +
Get Folders   Get Folders and Files   Create Folder    +
+ File Upload
+ +
+
+
+ URL: +
+ +
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmactualfolder.html b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmactualfolder.html new file mode 100644 index 00000000..98de246c --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmactualfolder.html @@ -0,0 +1,63 @@ + + + + + + + + + + + + +
+ +
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmcreatefolder.html b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmcreatefolder.html new file mode 100644 index 00000000..95b2d8bc --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmcreatefolder.html @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + +
+ +
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmfolders.html b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmfolders.html new file mode 100644 index 00000000..d5bf6daf --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmfolders.html @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + +
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmresourceslist.html b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmresourceslist.html new file mode 100644 index 00000000..9c10faba --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmresourceslist.html @@ -0,0 +1,152 @@ + + + + + + + + + + +
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmresourcetype.html b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmresourcetype.html new file mode 100644 index 00000000..85089cea --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmresourcetype.html @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + +
+ Resource Type
+ +
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmupload.html b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmupload.html new file mode 100644 index 00000000..c2bfdda1 --- /dev/null +++ b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/frmupload.html @@ -0,0 +1,109 @@ + + + + + + + + + +
+ + + + +
+ Upload a new file in this folder
+ + + + + +
 
+
+
+ + diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/ButtonArrow.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/ButtonArrow.gif new file mode 100644 index 0000000000000000000000000000000000000000..a355e5a449014d40f6e686aec027356b9e72c626 GIT binary patch literal 138 zcmZ?wbhEHb?doRyP?sz1@R%qk?NW&|^ p|eTtnS=Y)v`XcZE0Wm%(S+{n>TgunLDTH*uh2T&!5`4%$c3C%y;hIyZ_+f R9g8PVpFMx^^0^>`H30UMeqjIr literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/FolderOpened.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/FolderOpened.gif new file mode 100644 index 0000000000000000000000000000000000000000..0c5dd413efe52ef8df245c62d38abd3fb5531faf GIT binary patch literal 132 zcmZ?wbhEHb6krfwSj5I~?p*T!b93g*Vfg=l&j0`a85n>J5UKc+g^_`QjX?*<2C5Wb zU|{yl*mXxoV3&KA=w%M0D)qo6IdPeS4hsuYt(PRqFy=dMJ1DS(;Y^uj?AqnKDvKH$ h4uqvBmU_;}`s(90J$U9C1Ji>22?c3Bc`6JH)&Op|Ft`8! literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/FolderOpened32.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/FolderOpened32.gif new file mode 100644 index 0000000000000000000000000000000000000000..3e3fcf56cc471cb8f44c5edb5f23407f120b75a9 GIT binary patch literal 264 zcmV+j0r&n#Nk%w1VITk?0HOx~fPet_`1s7sW&i*HnVA6p%$fiHng9R)A^8LW000L7 zEC2ui03ZM$000Bcc)HyFFv{78y_ZT7y6*y^J)B{lXE-t?>Kf|WzJ*zbST3@`>l>e7 zXTYP`jx|Fqxg-!3v!5%8G&mPg=26MzE|piEc$^ay3Qmr2&HfAsp|@13xD0Kw@Z;yk4lxJy}TbYwv1&v{IeS%6~q)(8cfvHH9 z1FWAXijuHrXtPjLUZ*y?s=NoSsJ^hlX9AX3p}@()!dFnYxLu3VoKMAM-ecScv*YCD O=I1Nv>g((j2>?5Tf_QiU literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/FolderUp.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/FolderUp.gif new file mode 100644 index 0000000000000000000000000000000000000000..ad5bc202670bfa12195e767c28050b236089e940 GIT binary patch literal 132 zcmV-~0DJ#ONk%w1VGsZi0HOx~_xJbz|IYu;oSd8h&dy{1|C|5-0RR90A^8LW000L7 zEC2ui01yBW0009?c)Hv>5E}PD2&Iha2KgWnMapoU=v5GtnPtYC3GCs*Ml2M2edj

h0KmVcuWJD*FM9~M9v0;0gPtyf2D4lb<@_VjwB*Bz)~b>#zfjC@IsD5w|Oidff-V#g8}2kNqXb| z3*=vg3;-`U_%`_V2~bM`Zz#+RT^Sx39b;sQ1LKpSLm`J&E4zlMTrP)fis|!OD8)8jZh1;Bx0l-= z|5olUpD))!On*&71F@oVS4HgTQTv+9Iq!CAXG00xRC*#ce9p0;gBC#?#*V6(fm&gZ6(iJ-?<*$cbd*Pk~-cu8ti%)$w~m zF}hZExT5MvJfM2lQ43BrJ}jtiY)z1z1`ujO>Tf(rd_j!es+s?@v3Z@+H#wzy1)VN~ z@>^29db%?9H2l8(hXn%^4iv!}88EbHo(0)mmo&(%=?eP|btA=e;a;G2Q0DP z{-2wtWFHm{1TQkUDOA}p5{MVR_NXWH$j~Q!`r_`FL9mV*0)_R8X_@LhsNeFX+sNR+ zSfg*(_dLbjNJHJs(*8ZS&&0=-PQx#BQM^m*xk9gs-%qS znBFlNEK&BnY6)r2oZVd1)G6?=(lHPMAXN*g^vz7X7pY-0Z6&Aw2(%UNZ;9`9D~)47 zrrC(Kl^)sZ>YQrb0&SZ5`MJ2}gUe;0&|w@Y2TdTqQnY+2%QP)b0SNt_6c z?vCNb#g{jS zqzS1F7Yi`j+&oF3vk@0`c_AlBY-{D z_{yQ;#4A33CbnP$uv<4j5!vO4<#7+FSQ$k_Zp>IRAV4-*NE~_OF;=T}DqVd0X!Bwp wStD5{bcIq>&_CW_%>cTRhtqE{M<8rT)nil z!>wDl1_cGpIX9=cxY)_bDS6JhrAwC@0;zN7lIJ9Qd3jyCc5Tj_ImyXD;@rJ^_ma;g z8yY5`d;cG#;{UlRQ>F+A2pqe249Ed0F-%To`2XJ!Xvn$mii(QIjvZ@hX<_)!zyK8e z52b({B7x#h7DfgJLk1m?dXS$O*!~}wQ6SMQ*?%Hs(g~SEVHZ}EoNC$|w?XZ5<=d*g ztFz3tLuQ?K`?%vx*6#ZsEPVF1?cDu#wReB{`LnL&mDMf!E$w>6I^8|>%FP4+RFsZbl(HUW2zRj7*mpIc#(i7%CXAa&G$1 zb$HJi?&sBSc@@$XSXf!41ycM4mR3*HJEyr}!-dTZEo^K(lB@3>s9p2_-O+~A4J>>T HEDY8FY?%te literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/cs.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/cs.gif new file mode 100644 index 0000000000000000000000000000000000000000..b62bd026061c32a9c6e5e0b7bb0f63f29e2b3dff GIT binary patch literal 224 zcmZ?wbhEHbRA5kGSj5J_(8AEt(sJzBF^2yPK=2<7fDFZ-EQ|~cYz#UeQIJ{&=A{`~ z7yn&Y>lvzH@j8}i<%6w^G1qDysAQ$w*7Cw zb)JWJSY*qv{Jo}@*85%ep#_^mxz@^Ek!v|my$+pkc#iYHgR|<)Hv*145}Xzy*?#uy zW+72u^}VkibX`f?;iJ!XMxcLs>SwXJYbV{lxV?&3^z_y8;(O=jz293O)tFaX(OQ+m V(AC}3+t;1pIBD{fscM`I)&R&*NlyR( literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/dll.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/dll.gif new file mode 100644 index 0000000000000000000000000000000000000000..9b54964576b86bdff354807f15bf8d7b45c26a87 GIT binary patch literal 258 zcmZ?wbhEHbRA5kGSj5KA(!y};*s+$DmjC}5fZ#tE02zuuSr{1@*cfy`q9C;l%*Qjd z?)>vVsp-1YB3p;!?=`iwp6{W_Q5=rtdap9Js!4P!*0z~@{&9%b7hSQiZSf+3>%l=4 zbC?{xRHYJ^JbD!_YN>wVRmm#fINl3>={^y&r(Zh2+A*{0{Dp5OF3+;}xtHpSu`tBg zGna`sL=;C?F*CGG>|*W7kZQMY%L(e5o+#PMJTG{P!~)G$mL+Rfuc**k!@v;4&?&i6 zd2`3?whaZ+?fYX6_}i99@A5dc@yywS=ck>!bS&ZO&I-occkbT1e<$7H@sp>|OgR~> E0d_=epa1{> literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/doc.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/doc.gif new file mode 100644 index 0000000000000000000000000000000000000000..b557568b3d1ca19f9520b38a4c74de4e4abe0301 GIT binary patch literal 260 zcmZ?wbhEHbRA5kGSj5WE($aG5*f9o%{|rD320#W7DE?$&WME)r&;fBkY8jYMM(kq! zXJF^1sbKNi_rQt=M|)>{Hf)}-F6;CphX;mvXV)1h&Uf|7+UJv?arlkMs(3X`m9CP_ zv)3+@oW^!z&6Ep|?ycG7>(EguSdif;%5!b$-mI&xN9DLr?#s-QF^TF-@eHzvD|N|b zOf4v2R;u;NYnoIoQPMuWEU$95PkPn_w-&EyGa42)SIuA0xw3g_dy3)$ug*<%>t}2f z_1`SBb+_-1>AS@Cs_Z|y`tZVS$C7M#_MAI&;Bx2%Zo@;jPiRElfABCu;mOly&tE8T HGFSruuDNnD literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/exe.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/exe.gif new file mode 100644 index 0000000000000000000000000000000000000000..758499394afc5814b9da3e02d6b2996623ea3ece GIT binary patch literal 170 zcmZ?wbhEHbRA5kGSj5V3?AWoEmKKKp{}~v71PA~bK%n@Og^_`Ql|cu@0jXtR&X3r2 z=bynT&((V^Uh}fgcb2F-r!c4K#l%&et8O!#Y3N#3U@Bnaczx0Bu1&8c>vg>^p7?UH zZNaiF>{E4?pUHaCwNz`jZ!Y_szmxXvGM=^K87~uK*>B$dd{+jey?NVLeM+n`tOzMk R;r49r>h9_76XRsC1^{%DM?C-l literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/fla.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/fla.gif new file mode 100644 index 0000000000000000000000000000000000000000..923079fc6bbc36b0f3cef03c381d42fb9962c753 GIT binary patch literal 946 zcmdUs-ET{A9EZO<+S9YC?Wob8m!v&2wj#5`EE?U~b1XJhOV`LE=R#U_A%>LBTk4|S zDr>A5I=U%J+YM1$%pthhOzORHK?$-Hd%=a%c}WpTjsL=P_1t})AeVLSTYuigUXan3z0}9Eu?9h z4g>-bhr_|LX#{*U>a$wohya=sD6q38WU|M2-pz4VO66u*f^)O9+M!lQeLk<%>M)rS z@wg8m9uWb%T~Db3Za0TeOoiOEDnX+NMMe>+W=#Q_8XFq2BNU$qP77YIcVbf*696Fd zj|ur7p?-?809aV`H~#M@Ajvq{CbpuYvZaL}@K*dVj_I0@`ubTVq)>xVDrh4rms5^3Spr$J-t`?u;zkBE4#^Dz7jki4oSKP`v#fm9opMHCnZ;} zz1GBI{`)<+KP-zs;Tg$M-Djcl;f+t)SC6%Q2YyxP#?LXbXR8Ot7T)hy{Qg~6P_(9= zkQdf^l{=`riw%{(Tm{ue)-_qW)%G&WtZSVquZKD9wz*vvb@{U-2|A~ACfIDf%*e$P z?cUS3lIChBh={$LNy`98ZaqW`&r0BuD z4e~{vlsT1)@1B+?J7{TnC0!%;?@hifwn#f%#%SZ*H~5S4*^M6Md&ZgN-V?5w@~~=t z{vj(Nr0)EH;qJQ9o~mu@T=}_;Ri6HWl}~Q2nBysSj+e}{F=hLUxurkNGZZr8)2@BH zc*QJFQiqE)DV<5`2@a_I-->GXJTEl6a!_e0hA-#`rlP|j&e=bb4-A%VXakYh*qgmk zvHe)KIKK@GwKB_#Mav3D*S`~KYRv;jX8bUE+RCqgjUTO z!>wDl1_cGpIX9=cxY)_bDS6JhrAwC@0;zN7lIJ9Qd3jyCc5Tj_ImyXD;@rJ^_ma;g z8yY5`d;cG#;{UlRQ>F+A2pqe249Ed0F-%To`2XJ!Xvn$mii(QIjvZ@hX<=w#VE7Ld z{?7oU!6cAD3{d>Z!pOj2$e;sK4Du5L+y4VI3M85(`%k1yIw5l??81tYQ%!s0HmH5B zd|S15b(Xny$gJ~jA9viz+I|0nh0or$qwC-1oqj!Uc6Wh(V`Y&}TYG3|b5l!oMQw0E zU2}DBPkvau_T>@iN3<4dSxx*7gJJ}yHGHWubb-ZC< zSlGlWA{rr3aE6m1Db7hm;O9fu#z~Ku=EN*`;OKotHpw{YmFPBEF7n0SPh z-5{fcDcGTDk%p2-0>i<1jU3uMQ*0^|Rtd8?vkEi_C^|6;eq&3yu%Yol*KBr%M_EkF zYZ-VLm6m7(GRQOXifBkk9A$F2w>LUu!BPQ*!<<6eDjpXepmF>6I+p(?v&mbqn H!e9*mGolF; literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/htm.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/htm.gif new file mode 100644 index 0000000000000000000000000000000000000000..a9bdf0030869bb72b8115ce01f776f080576c7b9 GIT binary patch literal 1527 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 F06XGF$;AKw literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/js.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/js.gif new file mode 100644 index 0000000000000000000000000000000000000000..fe0c98e975c3e36eb30275c584f5cfdaf2bb0b52 GIT binary patch literal 274 zcmV+t0qy=rNk%w1VITk?0HOu}goFUb#>Rw%g#Z5l00030|NsC0{{R30A^8LW000I6 zEC2ui03ZM$000BmXe!+PP|3N9y*Oh*C>2_$F`ZY5XdwigX@IE+vgH@c7VW_sE=S8CAk;96zye@OEi4J7%yYsMBs14lfQi{kx>D-2z!ZXXBlpHGLXfU%%aXw0F>cMSa3P;YN@~85 zXs1wZZWz^I$sBYt#31HnOf{Juf_6(VW^93iSL5Ui2-3o>8d&O_<;{7#7K;Vu(OKI1 z;;nFSdR=&TNjQdbgFbA98Gu(;7;}G#8%mLqI%r`kjz?`jI+KK=hk>Yqn`^8sag(rR zlwho{Z*H_0P?(bV5^7Hid_8W(lfGF~=&@ij1P5SHA!N?yuXeKm(zYURrXvvm z02f3pqh`0;IW=%{9SIi~0s#OTdVEQ2Ol&zEl$9KW28V}scnlMdOpzUuf|p+%1)7?P z01XV0D}SVKrgN#Pn~IA~O|XEpgtw{zx&ywUzrd%Nxy1wo$jCSwwH=v>x)%i*2akTq zHq?X(tPK|nG~C`lOry0C7kB42j-ocmf3*q&0}5#WYDWEvmd}fogI6N`T1e}k!-tOq z(ohn}-H8`1Wc?9D>*5=M-@a9>NX;Y2kQ+xsakOZHqDGMu1u7}oQqW64yn5l}LW1JS wh3#O{lo3win^+%9nY4LhR#Tomen<@mRfIy6Sg}_1V5zIuua$U+O%VbBJG0Wu*8l(j literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/pdf.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/pdf.gif new file mode 100644 index 0000000000000000000000000000000000000000..4950ec87c13f9918009b13ae2db6732e07317cd0 GIT binary patch literal 567 zcmZ?wbhEHbRA5kGxT?c&?%cWOmX-nn0?EnA&*#k9yLa!kYuBE81--YlJa+8Z+O=z= zqN28L-TFKz$jQm+d3Ls!m)G;X$DT(;JvTIbuW9(arRBM$;q&V1=Rr|Zrc8OBocum0 z>iOQi_cS%Lv$N*_4RmsP@8tEoXUg-Qp6A)c?~98qEiH?Si~j=w0|?x^cMrw{^GPHW zf3h$#Fz5gw5P@~~Qom*ewqZhw7 zKBurJtN!*1^O!YOYu9|)YB8_t^WW6ca;6rh2(6sF+WgwC%rb5DN$RB?)j2&i$xXpi zXH<91Dwz;8FKv0soTXD@*19hVEcJDrymhOr!sL)mzWyOW976j8_W0~Otj(@`;%MZF z07c$2>YI-rW@Nm4^}HZEi}c~Me&>Z*v_(|+KXSSjEdDG&n311fNae_ty(exka&YjA z3b14-FdgnHb#0U7V94icWRT)}X6&|fc5Aw}g~uJWRtM%biI0UgiAk;v%sgIhj0-kh zc1hP(n4!^dprL6J+ky=&8(u%P2${xg#2}GysD*KoI+sXnLPBFRqx9EWgM|t!Ij4C= zs_n>1(muUHq|?e^qLB9WHL>g!0Swn9Z;EDi%b6A`9lXKl>+6tVt+!-b+&ZS;DoLw1 LBt|rC3S literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/ppt.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/ppt.gif new file mode 100644 index 0000000000000000000000000000000000000000..023431c16401f84d3be65bc112f9d0ac38a6aba1 GIT binary patch literal 254 zcmZ?wbhEHbRA5kGSj5KA0s;)jjvZrQVE7M2U;tz*{$ycfU|?g=0kVNA6&M(p4`=LR z`)6S1rm11^I`+Vd2SD zmu}o7y+v%V%zmD2V?;>*==MW7XXv~x5)aMfBoK?F zW6zSoF1YE1%;Xl!+`|~*F%!825>LA^kD=kxDLIWMmuhA@4aseU*nlRFhyRAJe17_T zednEgTH2cH8+u%Xi^xwCx~}JPxqLn^%Q8ZU<2Y8uilPXDpsK1M$f77FRLmRXFfhr&_Mo^w%1SiCjqEi$FfC3CdWW#Vx#+XI9hG0Y#wXle3m_taUP(G1Bk%%bi zd5%*7FENslF#v987>gJtA&5B&>WZQ=Fb5Pp9HGJyIv5N>H3vAAW!Z2z40t7sbU{*C zNskB`r|3|WSp{pFM$*GP~H>s_TyfBt%-F5T8;J#~8H?0~s+ zXXB9PW>r(KZ`8W`gfA8$e1fNO%=5#NJh;x~k4ES33@n~zf1OYA*v&hGHzSS4?YPRQ&w4x)AxOBAXi6+*mu{KIuGh-r|Wzv*e+FR&JZ$xH1zUYu>cG z&uzI9Yq2%M2+ZunHb+$N1&swYAuDxyBGP!IrSI*qb3{MTMZ?x0V6mWcE z|9I}gv+Zq5){pLIssew!b1CU`96NN@Lmgc;S&v>{nR6wN1qU|2T6&+L3hhaM(Mw%* z=Cbw&*_@SYooKank`p0e+U}nkcSN&;J5R;>2P@wHG7vNmO}g(4+wR?39xu;~%vQg< zR5uH^PL`HTjZgH3$5R)tj|9pq+DGQe#QhXwJ1IW#TFzKpt=1433zr-oN$pzWPW3N) z3vDY`$G2a5h9EB2ESek@@obZ&?AYo9?}a@b{_0IaO93CVWK6}Ix*b7F+;uhM-Q5?z=G__V3lY5wu~{Q`c_Bd p$!sXy?YxvMau4r&IQrbrt}oV%E%z;d_m?(Y)4DIetHV#c_%B&pUbg@M literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/swf.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/swf.gif new file mode 100644 index 0000000000000000000000000000000000000000..5df7de574966c8f4738c337d97c97b362cfb9f91 GIT binary patch literal 725 zcmZ?wbhEHbRA5kGxN5}U<>i%K-E;5x^Y7o^pSyOC!7ym=-o5X?f6va&j*5y}yLRol zbJrLYoz9&**D__!lqqwfidzf~4XbDFV}EmQU$yT;&^-7{zD+O2zova1E6 zTHe3^Uft3o5mY>7=~@QOpgC*zdL>sU7gulHdoH_rN_NlEDRY)aRZoe^Zn<~w`L%1; zdU|@^e}7+HUH$&~dj&K6yl zojL~V+xsHH@c`o|9UhyC1r82J zxwvJ|?KtsmX#fwSz>CD02Ob=1WztX6Yq-Gqe2S+w&#yg)7Bt*sVo!_W*x)34c}@Y7 zfW?X=#ttTpbtl%GzNUM0S(}W`jNJ=z7`bH9q-4uKzYW*nGST5k*x}Susnz8aaN);% zk-6GdPqd>OoiEPR_xjSi@ycd_dkEKgTed$ sRj~fxwYl+MVLG=`U+uM14J=|F5Athe7Cva=(YhfkFW{!(D!^b300g%yMgRZ+ literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/swt.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/swt.gif new file mode 100644 index 0000000000000000000000000000000000000000..7807c075c4082d561fd2f08c9a20ab4844d8cee4 GIT binary patch literal 724 zcmZ?wbhEHbRA5kGxN5}U<>i%K-E;5x^Y7o^pSyOC!7ym=-o5X?f6va&j*5y}yLRol zbJrLYoz9&**D__!lqqwfidzf~4XbDFV}EmQU$yT;&^-7{zD+O2zova1E6 zTHe3^Uft3o5mY>7=~@QOpgC*zdL>sU7gulHdoH_rN_NlEDRY)aRZoe^Zn<~w`L%1; zdU|@^e}7+HUH$&~dj6nnc&>9RAQ*ojz&Z49h@M%{gzUy7xRu}X=tXv8QUvk`Ss)JT|f=Hm=e z*-sPK9%x)~MqKsBv4C5Z9>La?bkD@4;205_cZ-x olY3FW;k4_-V{to`9yGAAE9cT`#-ccAhw4`jpjrZ$Po=+>rS<-e!jPxbB|+;eoCFoy*4?8no+b9O@c7 znu6TZTic2fJ10d?=r%vv9_HjDCz zuLzsz8*EthN5gskqy(RPrt4~5-RICX$;@Huv^eHaHuZ)ITCWCd#;pH0iBv~AT` zy{2TX>>jQNx6%cN_>V4GmXLeO{Gvrq>3P1>XKIxXvqqdd(YocrnJ3qzF1@(?>e;q6 V@7}Mula%u1>$flJKLt4%tN|w0c+CI+ literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/xls.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/xls.gif new file mode 100644 index 0000000000000000000000000000000000000000..afe724a3d06a51d2810f8d956f9a2042f4127e39 GIT binary patch literal 271 zcmV+q0r37uNk%w1VITk?0HOr|0E7U9goMV%#sB~S|NsC0|Nj6000000A^8LW000F5 zEC2ui03ZM$000BjSh^MdFg`|UAUNwy!l>ZIjhOQ>0g$e0%aVcMF>cMSLY`-rd^P}* zCI!Rz6e@y?mrRaCgd_3RX;pPt-(bsaDsRo0Mlj9@21Mm|c`cjG1E-q(&D!Bg(+7An)+;^79}G06U9=e5U{a literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/xml.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/xml.gif new file mode 100644 index 0000000000000000000000000000000000000000..4fae35662f0ff048d4004fdc74cda6b63f16d119 GIT binary patch literal 408 zcmZ?wbhEHbRA5kGI3mViIETS7`9A~09EN0urRTmg%=vGa%wTx#zu`GU28RFV-v2*# z?AW>g=g$5AZ}|T|Lkq*XbLR|`=d`r6eEY<3j9Dk`OoZE`nWr*xa<<-Z+HtMSBJn{^u;`V&6mSzrNEt?LH`~3Ax?=4JrY*0GX#-Qk=qQTsLv|qx~^^Qg0 iVuwC~AkkGZCpV>f)n+A~n&Y{-{p@Uu;&~j54AuZc3Y?7q literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/zip.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/32/zip.gif new file mode 100644 index 0000000000000000000000000000000000000000..7157f72ad82ea877fcb6995070a6563f56ef67d8 GIT binary patch literal 368 zcmZ?wbhEHbRA5kGI3mt)ZwdoL@|2!y|Nno#_WxKm!<2grhC%{EB};slLq*~Wvao7t(4YcThC6;%`Yr24Zi4PaOV6eOA}Gnc(I#ahItQPFz&i!!1#jo#hY7? xFH}7HYVuU?=dbU7{-(T977Tb`-^99F#>8mh!o%$X%5o`g8JrTL0dyds<4RV^aVB z|57BDbA&H|IUoo#=W(zoP=va&U;d8QcCBXbFE`S zIUx{AF)?dGF|DPoy|um8l$26hT61GsrId``*3Q<>#_!(N_xJC;lzX*=bN97#y`_w; zoRr4a-o4J&oRpmJ@Ar&zW5%telzVgk@2%FQQj}6cwR2kk-jp#pIT#oib8~zD|Nj60 z00000A^8LW002DzEC2ui01yBW000KCz@CstEEa{x;b0IOxF9c{E~y-RE*p%ErCXs53AutGm1iI;a&9 x77a8B0W|>v8K@@^5iJcNH3tSG6{sd9*aZa#2L%MDNFqA#5;_tRJN5NJ06RZNq>TUo literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/avi.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/avi.gif new file mode 100644 index 0000000000000000000000000000000000000000..6f3bac9bf1593da0934d7ce02064ef74e484c1a9 GIT binary patch literal 249 zcmZ?wbhEHb6krfwI3mMvZjPa$VRCZvIm6^RbLO1;{{8!$ImuhMZvFrNTynDExpT=; zQBh7#PUq$Tr48R-J9cgk!?|-n9>bhupf;f9IseZw{GY?n($aG5*f9nMhW}syWI%x8 zPZmZ71{nq&5Eo=818bRrdQwVemqvT;n`v8Ts6~~;GQZY}p1#>*LidNJlNo(daVY@{ zWwUaL(+k*J$tlM*YK{1NYI`ZnW)mW{>#=ysy0hLX0`cg&BbkJ4}^gUQzaPeB<)#Q2S7Oc~`%`->q#0Q%_#rF={k17wA&Fi)#cna}i9!sV4Aub8Vl3$Z literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/cs.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/cs.gif new file mode 100644 index 0000000000000000000000000000000000000000..4d927230b980dbbdca5b06f12a98449647ca0fe7 GIT binary patch literal 128 zcmZ?wbhEHb6krfwSj5V}(8AEt(sJzBF$M;P|6l-Q0DA+ z&boq$o(!ph*Rni6Ts&TSB!TY&dxW+s#|ou&Pgs`UaTDBbb9LQ}wC%4m<4%bCYbdc5 Z?pbo_Mu}eVr8OUpyyY@Z@L*!F1^}CaF8}}l literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/default.icon.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/default.icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..6ce26a4dc516f5962623445396862c753a875900 GIT binary patch literal 113 zcmZ?wbhEHb6krfwSj56`?AWoEmKFvEhW}syWI%x8PZmZ71{MY#5ErDDf!WMMz)wYHuMVva8^OvzO GSOWls#w7~? literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/dll.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/dll.gif new file mode 100644 index 0000000000000000000000000000000000000000..48d445acd2feab875c2d42c246e9010814314bb6 GIT binary patch literal 132 zcmZ?wbhEHb6krfwSj5KA(!%inKf|$O$6A0a1|S;*fDFZ-EQ|~cYz#U;Hc+Ji0|T>X z#^yWU3Z{52m-ukf%k`k3yP%3-*W8u93=RcNt9)D@gcWkI9QhQriC6L4&!=I+p7|fF f&bcuq9o#ATcbQ|zt0ha__CHv$#zk+n5Q8-UbUQQ< literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/doc.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/doc.gif new file mode 100644 index 0000000000000000000000000000000000000000..6535b4c0e72aa2cded728e28ee6440c1fe0a954c GIT binary patch literal 140 zcmZ?wbhEHb6krfwSj5WE($aG5*f9o%{|rD320#W7DE?$&WME)r&;fBkY8jXVBe?FY z+rZ$Y&Fb8_(OO=7Vq=(Ufb*})xCcUxyE@a|Sq$%KqPl7^Ro&=#&h4hzE(^L jR*hU`(7bxhmuZnxV$QBxlGW+R@Sr5BCvfLoP6lfLw_`LY literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/exe.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/exe.gif new file mode 100644 index 0000000000000000000000000000000000000000..315817f5d93a2a6fa5db3ca5e1c9d9e72297c1b0 GIT binary patch literal 109 zcmZ?wbhEHb6krfwSj5V3?AWoEmKKKpAi%%?qJbn3DE?$&WME)r&;fBkY8jY~B6i*R zXJF>^RLSWASNXZw&O8U&G9N8irFy(4+h@r~EB~#sJ|Y3ajSDg!Grv<&><*gAz+epk D58Wo= literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/fla.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/fla.gif new file mode 100644 index 0000000000000000000000000000000000000000..8f91a98ecb196dbcf5424e266ca58d216cd4a9eb GIT binary patch literal 382 zcmZ?wbhEHb6krfwxT?XhR8hdo%PTuO`&>{EgJIPFI}I;|Dp zc%Pgc6&3aV`}^-fUeCQOdwP0~X-ZUASHFM${{R2~3=9kq63CzsDE?$&WMI%>&;gkP z@)HBwYzL7p7om#2#si)wL?(F!2%98Cm<2ZVZ~3Ch>UA|+?3QVy&oYC{!ISECotivn zi=MmpqCcH_Dg71<%DDkb)jrCNqP!hVYOOUI?7WH`68uu^LH$n3d{a32xdr%?``R=Z z6crRi1i6?MXU<-+T7iX|hf_g(S&gzHs}Re21x4km3ChAO(z2|q%0r28usf7#SE?8FWBAkXi<2r--O4 z|FS1KXsZVL9;`07c&+ei^1O2k*6G|{AtTej{=zM0yDLAt%B`L9e?;#s+CMY!M%Jo; V3vL<)Qnkyb>9`50G6*qP0|1+DE=>Rc literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/htm.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/htm.gif new file mode 100644 index 0000000000000000000000000000000000000000..0b5d6ba1fc35ab7dccc0f27ef14f2bdbefe75859 GIT binary patch literal 621 zcmd6k&ui0A0Dxb+VB4{+?YgxUTV^K{qg5LnvM_(lIJz`RQF6>pa?C||-g?<)1gmc# znuA~%2n(Jb2oms;!(;>zd@zI@a}ZpP&%@y1>FN9{{7&ETgKuNdUy&bHKm{BPf$bAQ zctp74_-+tm!XZvY7?`FD-7q4V=#n7LI(|kO*D!S=`qxAh%U-Hr9ul5XK60@Xu`r=B zBBGZmgli+L*e=OYPhmpijCBxUoJ%MbLzXcv!BBQQ+xAQo#TmCOWTHs45W)$B zkpBbxmvnv$IRJ*Bds27u1Qfn*4!1S;sax6}KQYjbQ3B6j7}Xo@=~BM;N(1VyYBVSI z8e>(xbhXt4Mx}Z?-_VC5xY?bZoxa#MW@hqN!goSp%D6mNTdCj8Pw4U5t#bL!;#_;O zeyAHlYkKhW=-%Y@`E^~83TFlv`p5l+YYX!m-)p~?m8p91_~pKu6ZFTu!$)iDJFV5T zZ$4EQ5B8T%6}v|Mhfpk^(}do$596)Zxh8s0**y3H8nw1;?w$YkcG+37K7V|Fe|HOj F)j#Az*75)V literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/html.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/html.gif new file mode 100644 index 0000000000000000000000000000000000000000..0b5d6ba1fc35ab7dccc0f27ef14f2bdbefe75859 GIT binary patch literal 621 zcmd6k&ui0A0Dxb+VB4{+?YgxUTV^K{qg5LnvM_(lIJz`RQF6>pa?C||-g?<)1gmc# znuA~%2n(Jb2oms;!(;>zd@zI@a}ZpP&%@y1>FN9{{7&ETgKuNdUy&bHKm{BPf$bAQ zctp74_-+tm!XZvY7?`FD-7q4V=#n7LI(|kO*D!S=`qxAh%U-Hr9ul5XK60@Xu`r=B zBBGZmgli+L*e=OYPhmpijCBxUoJ%MbLzXcv!BBQQ+xAQo#TmCOWTHs45W)$B zkpBbxmvnv$IRJ*Bds27u1Qfn*4!1S;sax6}KQYjbQ3B6j7}Xo@=~BM;N(1VyYBVSI z8e>(xbhXt4Mx}Z?-_VC5xY?bZoxa#MW@hqN!goSp%D6mNTdCj8Pw4U5t#bL!;#_;O zeyAHlYkKhW=-%Y@`E^~83TFlv`p5l+YYX!m-)p~?m8p91_~pKu6ZFTu!$)iDJFV5T zZ$4EQ5B8T%6}v|Mhfpk^(}do$596)Zxh8s0**y3H8nw1;?w$YkcG+37K7V|Fe|HOj F)j#Az*75)V literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/jpg.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/jpg.gif new file mode 100644 index 0000000000000000000000000000000000000000..634b386139ac697806757c8d34bed36b5a2e5b45 GIT binary patch literal 125 zcmZ?wbhEHb6krfwSj5WE($aG5*s=fr|F^U-00EEzq8Jzyf3h$#Ft9S{fH)wv49rdu zQCI$DPjt{$4fH)&U2ySQ;nn1M=N7Efxy>W1vu4h(L$B8CcA0nH;sGzmk%w`nkI!Gr Xww$>lL&HF-cG)x?H=$exAqHyz+f*-Z literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/js.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/js.gif new file mode 100644 index 0000000000000000000000000000000000000000..4ea17d452edaf63a5f599042879cc05a3b05905d GIT binary patch literal 139 zcmZ?wbhEHb6krfwSj524(!y};*s=frfs7Ug28RDY78of0WC7DUAQGgOfjPip*Bukp zV`_&dr*>@0-Etv>LB&I4!HI?a)6OrXSt1KqtHVsZE6pPt-9GvFF^A}XUv*^C r;ak22hG!S;yY$xUOU2HaM|C{I+Ek;sd6_hJPfqX2@(WjGV6X-NZuBx8 literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/mp3.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/mp3.gif new file mode 100644 index 0000000000000000000000000000000000000000..6f3bac9bf1593da0934d7ce02064ef74e484c1a9 GIT binary patch literal 249 zcmZ?wbhEHb6krfwI3mMvZjPa$VRCZvIm6^RbLO1;{{8!$ImuhMZvFrNTynDExpT=; zQBh7#PUq$Tr48R-J9cgk!?|-n9>bhupf;f9IseZw{GY?n($aG5*f9nMhW}syWI%x8 zPZmZ71{nq&5Eo=818bRrdQwVemqvT;n`v8Ts6~~;GQZY}p1#>*LidNJlNo(daVY@{ zWwUaL(+k*J$tlM*YK{1NYI`ZnW)mW{>#=ysy0hLX0`cgv>ev^SyhYS64r8X?YK12So`82>fRNfqVDv z{r?YPGARCJVPs&CWzYdhfb3*oO-@kHONmUIxgsy-^|qPQW|^Ek`f1r)oAdK_#q~cu zbtPl{l^0V5_T;S=Z~hQc)}ed!aA|{HGz;^B2|Yz@;*5(PawLd_EmCDzp}@k>p>l2} b%e-`vLRL<;1{wB3!FE?Ijs6J}6d9}meKBOp literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/ppt.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/ppt.gif new file mode 100644 index 0000000000000000000000000000000000000000..877a8c8679545e4ea31ea6d66c344cb1a69b9b60 GIT binary patch literal 139 zcmZ?wbhEHb6krfwSj5KA0s;)jjvZrQVE7M2U;tz*{$ycfU|?g=0kVNA1sE8Z12VYo zth>!zWU*s{&Jd<`>yWH_^+2I#AA{J%s7G|&p0BKw|IsgCw literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/rdp.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/rdp.gif new file mode 100644 index 0000000000000000000000000000000000000000..916cd7e639de75276e3fac7d4a4466479285fbc0 GIT binary patch literal 606 zcmchU&ubGw6vrpo{HP7Ji>awd!Ny-jsS1MH`U@LtlcrQ_s3zIwU|DauxyQX|x?q%1 zq|BkhKtPz|fCvMEEP~*e(;VkGD5!f}3&P@Qocc%jk8i|G!%@<`A|b55u$#WP!&Un9G3XLps}Wj7D9Eqf$#fJ8H5p*G7e=-si0JO zNL85WQFn?71c9mX?Aw@`|sb+UAvcE-BaB&M=_}Q+_`f-OSf)4 zb}qYTDT7yb%al3Su3fu#?|E`@wO3T}oV9xy6rIkUyY~J2djY3pLqo%$?CQP8u1N$H zzyJQ;%gbx&)?@dcKL={->FM!Gt_Fhl&)@(5|DS<@0YU;9lmo?|EQ|~c>I^y{qdwUe4Gl+*;-lwkB+sYUz^1v;|)#6j^vpu37T# zmUD%0Y=v2e3tNhqVwDfO5R;r7Q-i8ZOSQU^94jjq2ZyAL>I5eRE_r!5X$}Qpc9pr4 zSQql}D#)`c&1sz^&mzyuz#u2Ed6fdUDiZ^b6pNe!-zs$lh21Qw^6W*$K1?FwqAc7B ROoA@15eoGR5k8I#)&SOyb=v>{ literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/swt.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/swt.gif new file mode 100644 index 0000000000000000000000000000000000000000..314469da14a51a3079a95b10deff5e4af2f14dd3 GIT binary patch literal 388 zcmZ?wbhEHb6krfwxT?;;U>Fn?71c9mX?Aw@`|sb+UAvcE-BaB&M=_}Q+_`f-OSf)4 zb}qYTDT7yb%al3Su3fu#?|E`@wO3T}oV9xy6rIkUyY~J2djY3pLqo%$?CQP8u1N$H zzyJQ;%gbx&)?@dcKL={->FM!Gt_Fhl&)@(5|DS<@0YU;9lmo?|EQ|~c>I^y{qdwUe4Gl+*;-lwkB+sYUz^1v;|)#6j^vpu37T# zmUD%0Y=v2e3tNhqVwDfO5R;r7Q-i8ZOSQU^94jjq2ZyAL>I5eRE_r!5X$}Qpc9pr4 zSQql}D#)`c&1sz^&mzyuz#u2Ed6fdUDiZ^b6pNe!-zs$lh21Qw^6W*$K1?FwqAc7B ROoA@15eoGR5k8I#)&SOyb=v>{ literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/txt.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/txt.gif new file mode 100644 index 0000000000000000000000000000000000000000..1511ba3e9fa53d21b23d74e5430199f52107b8c6 GIT binary patch literal 122 zcmZ?wbhEHb6krfwSj586($aG5*f9nMhW}syWI%x8PZmZ71{MY#5ErDDf!W?edQV`N^25{1 dUq#HdJfRXbF>~kLGf7@*-Ks0MSTQnK0|4?|F*N`H literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/xls.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/xls.gif new file mode 100644 index 0000000000000000000000000000000000000000..f57715d6a0cf03d3d392fb78d1477fcb1756edc1 GIT binary patch literal 138 zcmZ?wbhEHb6krfwSj5V}(86%+*f9nm-O}BIae?UME_83{kohvOm*4@L8Aw=661Zc_WCg}SOWmuf-oWg literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/xml.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/xml.gif new file mode 100644 index 0000000000000000000000000000000000000000..455992877e103d01bd247e45d96e33412ae706d1 GIT binary patch literal 231 zcmZ?wbhEHb6krfwI3mEn(9&}3*fGQ8|AuoI4Cnke{QuwZ+HPD{sTJjBd9|(eHjSNmO^r^D{SzDo6d9}m>N8Dk literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/zip.gif b/oss/vtiger/trunk/include/fckeditor/editor/filemanager/browser/default/images/icons/zip.gif new file mode 100644 index 0000000000000000000000000000000000000000..b1e24921e56f8b71282f953c690d152dd986f6ff GIT binary patch literal 235 zcmZ?wbhEHb6krfwI3mLE|M^yid-wjYW%$3>>;GEC|Np;dAN!x(^Z)<'数量', 'Price'=>'单价', 'Discount'=>'折扣', +'LBL_ADD_BUTTON'=>'新建', // Added after 5.0.4 GA //Added to Fix i18N issue in Email Template diff --git a/oss/vtiger/trunk/modules/PickList/language/zh_cn.lang.php b/oss/vtiger/trunk/modules/PickList/language/zh_cn.lang.php index f5ffec17..9a607414 100644 --- a/oss/vtiger/trunk/modules/PickList/language/zh_cn.lang.php +++ b/oss/vtiger/trunk/modules/PickList/language/zh_cn.lang.php @@ -1,34 +1,43 @@ 'Assign', - 'ADD_PICKLIST_VALUES'=>'Add picklist values', - 'LBL_EXISTING_PICKLIST_VALUES'=>'Existing picklist values', - 'LBL_PICKLIST_ADDINFO'=>'Add new entries here', - 'LBL_SELECT_ROLES'=>'Select roles', - 'LBL_NON_EDITABLE_PICKLIST_ENTRIES'=>'Non-editable values', - 'EDIT_PICKLIST_VALUE'=>'Edit picklist values', - 'LBL_EDIT_HERE'=>'Replace with: ', - 'LBL_SELECT_TO_EDIT'=>'Select a value to edit: ', - 'DELETE_PICKLIST_VALUES'=>'Delete picklist values', - 'LBL_REPLACE_WITH'=>'Replace with: ', - 'ASSIGN_PICKLIST_VALUES'=>'Assign Picklist Values', - 'LBL_PICKLIST_VALUES'=>'Available picklist values', - 'LBL_PICKLIST_VALUES_ASSIGNED_TO'=>'Assigned picklist values for ', - 'LBL_ADD_TO_OTHER_ROLES'=>'Add to other roles', - 'LBL_OK_BUTTON_LABEL'=>'Ok', - 'LBL_SELECT_ROLES'=>'Select roles', - 'LBL_DISPLAYED_VALUES'=>'All accessible values for the role are shown below', + 'LBL_ASSIGN_BUTTON'=>'指定下拉选择', + 'ADD_PICKLIST_VALUES'=>'添加下拉选择列表变量', + 'LBL_EXISTING_PICKLIST_VALUES'=>'存在的下拉选择变量', + 'LBL_PICKLIST_ADDINFO'=>'在这里添加新实体', + 'LBL_SELECT_ROLES'=>'选择角色', + 'LBL_NON_EDITABLE_PICKLIST_ENTRIES'=>'不可编辑的变量', + 'EDIT_PICKLIST_VALUE'=>'编辑下拉选择变量', + 'LBL_EDIT_HERE'=>'用下面的下拉选择变量替换:', + 'LBL_SELECT_TO_EDIT'=>'选择一个需要编辑的下拉选择变量:', + 'DELETE_PICKLIST_VALUES'=>'删除下拉选择列表变量', + 'LBL_REPLACE_WITH'=>'用下面的下拉选择变量替换:', + 'ASSIGN_PICKLIST_VALUES'=>'指定下拉选择变量', + 'LBL_PICKLIST_VALUES'=>'可用下拉选择变量', + 'LBL_PICKLIST_VALUES_ASSIGNED_TO'=>'指定下拉选择变量为用户角色: ', + 'LBL_ADD_TO_OTHER_ROLES'=>'为其他角色指定下拉选择变量', + 'LBL_OK_BUTTON_LABEL'=>'确定', + 'LBL_SELECT_ROLES'=>'选择角色', + 'LBL_DISPLAYED_VALUES'=>'下面显示了当前用户角色所有可以被指定的选择变量', ); ?> diff --git a/oss/vtiger/trunk/modules/Settings/language/zh_cn.lang.php b/oss/vtiger/trunk/modules/Settings/language/zh_cn.lang.php index 41c05cc1..964a8729 100644 --- a/oss/vtiger/trunk/modules/Settings/language/zh_cn.lang.php +++ b/oss/vtiger/trunk/modules/Settings/language/zh_cn.lang.php @@ -45,8 +45,10 @@ $mod_strings = Array( 'LBL_MODULE_NAME' => '设定', - 'LBL_MODULE_TITLE' => '设定: 首页', - 'LBL_LIST_CONTACT_ROLE' => '职位', + +'LBL_MODULE_TITLE' => '设定: 首页', + +'LBL_LIST_CONTACT_ROLE' => '职位',