Index: admin/system_presets/simple/email_events_emailevents.php =================================================================== --- admin/system_presets/simple/email_events_emailevents.php (revision 15111) +++ admin/system_presets/simple/email_events_emailevents.php (working copy) @@ -15,7 +15,7 @@ // toolbar buttons $remove_buttons = Array ( // list of all email templates -// 'email_message_list' => Array ('new_item', 'edit', 'delete', 'approve', 'decline', 'frontend_mail', 'view', 'dbl-click'), + 'email_message_list' => Array (/*'new_item', 'edit', 'delete', 'approve', 'decline', 'frontend_mail', 'view',*/ 'export', /*'dbl-click'*/), // edit email edit - general tab // 'email_message_edit' => Array ('select', 'cancel', 'reset_edit', 'prev', 'next'), @@ -59,6 +59,6 @@ // hide columns in grids $hide_columns = Array ( -// 'Default' => Array ('EventId', 'Description', 'Event', 'Module', 'Type', 'Enabled'), -// 'Emails' => Array ('EventId', 'Event', 'Subject', 'Description', 'Type', 'Enabled', 'Module', 'FrontEndOnly'), +// 'Default' => Array ('EventId', 'Description', 'Event', 'Module', 'Type', 'Enabled', 'LastChanged'), +// 'Emails' => Array ('EventId', 'Event', 'Subject', 'Description', 'Type', 'Enabled', 'Module', 'FrontEndOnly', 'LastChanged'), ); \ No newline at end of file Index: admin/system_presets/simple/phrases_phrases.php =================================================================== --- admin/system_presets/simple/phrases_phrases.php (revision 15111) +++ admin/system_presets/simple/phrases_phrases.php (working copy) @@ -17,7 +17,7 @@ // 'phrase_edit' => Array ('select', 'cancel', 'reset_edit', 'prev', 'next'), // single phrase list -// 'phrases_list_st' => ('new_item', 'edit', 'delete', 'view', 'dbl-click'), + 'phrases_list_st' => Array (/*'new_item', 'edit', 'delete', 'view',*/ 'export', /*'dbl-click'*/), // edit phrase // 'phrase_edit_single' => Array ('select', 'cancel', 'reset_edit', 'prev', 'next'), Index: core/admin_templates/languages/email_message_list.tpl =================================================================== --- core/admin_templates/languages/email_message_list.tpl (revision 15111) +++ core/admin_templates/languages/email_message_list.tpl (working copy) @@ -15,85 +15,48 @@ a_toolbar = new ToolBar(); - a_toolbar.AddButton( - new ToolBarButton( - 'new_item', - '', - function() { - std_precreate_item('emailevents', 'languages/email_message_edit'); - } - ) - ); + + std_precreate_item('emailevents', 'languages/email_message_edit'); + - a_toolbar.AddButton( - new ToolBarButton( - 'edit', - '::', - edit - ) - ); + + edit(); + - a_toolbar.AddButton( - new ToolBarButton( - 'delete', - '', - function() { - std_delete_items('emailevents'); - } - ) - ); + + std_delete_items('emailevents'); + a_toolbar.AddButton( new ToolBarSeparator('sep1') ); - a_toolbar.AddButton( - new ToolBarButton( - 'approve', - '', - function() { - submit_event('emailevents', 'OnMassApprove'); - } - ) - ); + + submit_event('emailevents', 'OnMassApprove'); + - a_toolbar.AddButton( - new ToolBarButton( - 'decline', - '', - function() { - submit_event('emailevents', 'OnMassDecline'); - } - ) - ); + + submit_event('emailevents', 'OnMassDecline'); + - a_toolbar.AddButton( - new ToolBarButton( - 'frontend_mail', - '', - function() { - submit_event('emailevents', 'OnFrontOnly'); - } - ) - ); + + submit_event('emailevents', 'OnFrontOnly'); + + + open_popup('emailevents', 'OnExportEmailEvents', 'regional/languages_export'); + + a_toolbar.AddButton( new ToolBarSeparator('sep2') ); - a_toolbar.AddButton( - new ToolBarButton( - 'view', - '', - function() { - show_viewmenu(a_toolbar,'view'); - } - ) - ); + + show_viewmenu(a_toolbar,'view'); + a_toolbar.Render(); - Index: core/admin_templates/languages/phrase_edit.tpl =================================================================== --- core/admin_templates/languages/phrase_edit.tpl (revision 15111) +++ core/admin_templates/languages/phrase_edit.tpl (working copy) @@ -92,7 +92,7 @@ - + Index: core/admin_templates/languages/phrase_list.tpl =================================================================== --- core/admin_templates/languages/phrase_list.tpl (revision 15111) +++ core/admin_templates/languages/phrase_list.tpl (working copy) @@ -5,37 +5,41 @@ - Index: core/admin_templates/regional/languages_export.tpl =================================================================== --- core/admin_templates/regional/languages_export.tpl (revision 15111) +++ core/admin_templates/regional/languages_export.tpl (working copy) @@ -29,6 +29,13 @@ + + + + + + +
-
@@ -39,75 +46,77 @@ - + + - - - - - - - - + + + + + + + + - - - + + + - - + + + Index: core/admin_templates/regional/phrases_edit.tpl =================================================================== --- core/admin_templates/regional/phrases_edit.tpl (revision 15111) +++ core/admin_templates/regional/phrases_edit.tpl (working copy) @@ -85,7 +85,7 @@ - + Index: core/install/install_schema.sql =================================================================== --- core/install/install_schema.sql (revision 15111) +++ core/install/install_schema.sql (working copy) @@ -112,6 +112,7 @@ Module varchar(40) NOT NULL DEFAULT 'Core', Description text, `Type` int(11) NOT NULL DEFAULT '0', + LastChanged int(10) unsigned DEFAULT NULL, PRIMARY KEY (EventId), KEY `Type` (`Type`), KEY Enabled (Enabled), Index: core/install/upgrades.sql =================================================================== --- core/install/upgrades.sql (revision 15114) +++ core/install/upgrades.sql (working copy) @@ -2648,3 +2648,5 @@ WHERE ModuleOwner = 'In-Portal' AND Section = 'in-portal:configure_advanced' AND Heading = 'la_section_SettingsAdmin' AND DisplayOrder > 40.11; INSERT INTO SystemSettings VALUES(DEFAULT, 'DefaultGridPerPage', '20', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsAdmin', 'la_config_DefaultGridPerPage', 'select', '', '10=+10||20=+20||50=+50||100=+100||500=+500', 40.12, 0, 0, NULL); + +ALTER TABLE EmailEvents ADD LastChanged INT UNSIGNED NULL; Index: core/units/email_events/email_events_config.php =================================================================== --- core/units/email_events/email_events_config.php (revision 15111) +++ core/units/email_events/email_events_config.php (working copy) @@ -45,7 +45,7 @@ // for separate grid with email editing 'email_message_list' => Array ( 'prefixes' => Array ('emailevents_List'), 'format' => "!la_title_EmailMessages!", - 'toolbar_buttons' => Array ('new_item', 'edit', 'delete', 'approve', 'decline', 'frontend_mail', 'view', 'dbl-click'), + 'toolbar_buttons' => Array ('new_item', 'edit', 'delete', 'approve', 'decline', 'frontend_mail', 'export', 'view', 'dbl-click'), ), 'email_message_edit' => Array ( @@ -192,6 +192,7 @@ 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Text_Admin', 0 => 'la_Text_User'), 'use_phrases' => 1, 'not_null' => 1, 'unique' => Array ('Event'), 'required' => 1, 'default' => 0 ), + 'LastChanged' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => NULL), ), 'VirtualFields' => Array ( @@ -233,9 +234,10 @@ 'EventId' => Array ('title' => 'column:la_fld_Id', 'filter_block' => 'grid_range_filter', 'width' => 70, ), 'Description' => Array ('filter_block' => 'grid_like_filter', 'width' => 250, ), 'Event' => Array ('filter_block' => 'grid_like_filter', 'width' => 250, ), - 'Module' => Array ('filter_block' => 'grid_options_filter', 'width' => 100, ), + 'Module' => Array ('filter_block' => 'grid_multioptions_filter', 'width' => 100, ), 'Type' => Array ('filter_block' => 'grid_options_filter', 'width' => 120, ), 'Enabled' => Array ('title' => 'column:la_fld_Status', 'filter_block' => 'grid_options_filter', 'width' => 80, ), + 'LastChanged' => Array ('title' => 'column:la_fld_Modified', 'filter_block' => 'grid_date_range_filter', 'width' => 150), ), ), @@ -253,8 +255,9 @@ 'Description' => Array ('filter_block' => 'grid_like_filter', 'width' => 250, ), 'Type' => Array ('filter_block' => 'grid_options_filter', 'width' => 60, ), 'Enabled' => Array ('filter_block' => 'grid_options_filter', 'width' => 70, ), - 'Module' => Array ('filter_block' => 'grid_options_filter', 'width' => 100, ), + 'Module' => Array ('filter_block' => 'grid_multioptions_filter', 'width' => 100, ), 'FrontEndOnly' => Array ('filter_block' => 'grid_options_filter', 'width' => 120, 'hidden' => 1), + 'LastChanged' => Array ('title' => 'column:la_fld_Modified', 'filter_block' => 'grid_date_range_filter', 'width' => 150), ), ), ), Index: core/units/email_events/email_events_event_handler.php =================================================================== --- core/units/email_events/email_events_event_handler.php (revision 15111) +++ core/units/email_events/email_events_event_handler.php (working copy) @@ -31,6 +31,7 @@ 'OnFrontOnly' => Array ('self' => 'edit'), 'OnSaveSelected' => Array ('self' => 'view'), 'OnProcessEmailQueue' => Array ('self' => 'add|edit'), + 'OnExportEmailEvents' => Array ('self' => 'view'), 'OnSuggestAddress' => Array ('self' => 'add|edit'), @@ -1044,9 +1045,36 @@ $object->SetDBField('ReplacementTags', $replacement_tags ? serialize($replacement_tags) : NULL); } + + if ( $this->translationChanged($object) ) { + $object->SetDBField('LastChanged_date', TIMENOW); + $object->SetDBField('LastChanged_time', TIMENOW); + } } /** + * Checks, that at least one of phrase's translations was changed + * + * @param kDBItem $object + * @return bool + */ + function translationChanged(&$object) + { + $changed_fields = array_keys( $object->GetChangedFields() ); + $translation_fields = Array ('Subject', 'Body'); + + foreach ($changed_fields as $changed_field) { + $changed_field = preg_replace('/^l[\d]+_/', '', $changed_field); + + if ( in_array($changed_field, $translation_fields) ) { + return true; + } + } + + return false; + } + + /** * Validates address using given field prefix * * @param kEvent $event @@ -1213,4 +1241,32 @@ $object->SetError($field, 'parsing_error'); } } + + /** + * Stores ids of selected phrases and redirects to export language step 1 + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnExportEmailEvents(kEvent &$event) + { + if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) { + $event->status = kEvent::erFAIL; + return; + } + + $this->Application->setUnitOption('phrases', 'AutoLoad', false); + + $this->StoreSelectedIDs($event); + $this->Application->StoreVar('export_language_ids', $this->Application->GetVar('m_lang')); + + $event->setRedirectParams( + Array ( + 'phrases.export_event' => 'OnNew', + 'pass' => 'all,phrases.export', + 'export_mode' => $event->Prefix, + ) + ); + } } \ No newline at end of file Index: core/units/helpers/language_import_helper.php =================================================================== --- core/units/helpers/language_import_helper.php (revision 15111) +++ core/units/helpers/language_import_helper.php (working copy) @@ -443,26 +443,42 @@ } /** - * Sets language pack data limits for export + * Sets language pack data limit for export * - * @param mixed $phrases - * @param mixed $email_events + * @param string $prefix + * @param string $data */ - function setExportLimits($phrases, $email_events) + function setExportLimit($prefix, $data = null) { - if (!is_array($phrases)) { - $phrases = str_replace(',', "\n", $phrases); - $phrases = preg_replace("/\n+/", "\n", str_replace("\r", '', trim($phrases))); - $phrases = $phrases ? array_map('trim', explode("\n", $phrases)) : Array (); + if ( !isset($data) ) { + $key_field = $prefix == 'phrases' ? 'Phrase' : 'Event'; + $ids = $this->getExportIDs($prefix); + + $sql = 'SELECT ' . $key_field . ' + FROM ' . $this->Application->getUnitOption($prefix, 'TableName') . ' + WHERE ' . $this->Application->getUnitOption($prefix, 'IDField') . ' IN (' . $ids . ')'; + $rs = $this->Conn->QueryRaw($sql); + + if ( $this->Conn->RowCount($rs) ) { + $data = ''; + + while ( ($row = $this->Conn->GetNextRow($rs)) ) { + $data .= ',' . $row[$key_field]; + } + + $data = substr($data, 1); + } + + $this->Conn->Destroy($rs); } - if (!is_array($email_events)) { - $email_events = str_replace(',', "\n", $email_events); - $email_events = preg_replace("/\n+/", "\n", str_replace("\r", '', trim($email_events))); - $email_events = $email_events ? array_map('trim', explode("\n", $email_events)) : Array (); + if ( !is_array($data) ) { + $data = str_replace(',', "\n", $data); + $data = preg_replace("/\n+/", "\n", str_replace("\r", '', trim($data))); + $data = $data ? array_map('trim', explode("\n", $data)) : Array (); } - $this->_exportLimits = Array ('phrases' => $phrases, 'emailevents' => $email_events); + $this->_exportLimits[$prefix] = $data; } /** @@ -1101,4 +1117,48 @@ return array_key_exists($country_id . '-' . $state_iso, $cache) ? $cache[$country_id . '-' . $state_iso] : false; } + + /** + * Returns comma-separated list of IDs, that will be exported + * + * @param string $prefix + * @return string + * @access public + */ + public function getExportIDs($prefix) + { + $ids = $this->Application->RecallVar($prefix . '_selected_ids'); + + if ( $ids ) { + // some records were selected in grid + return $ids; + } + + $tag_params = Array ( + 'grid' => $prefix == 'phrases' ? 'Phrases' : 'Emails', + 'skip_counting' => 1, + 'per_page' => -1 + ); + + $list =& $this->Application->recallObject($prefix, $prefix . '_List', $tag_params); + /* @var $list kDBList */ + + $sql = $list->getCountSQL($list->GetSelectSQL()); + $sql = str_replace('COUNT(*) AS count', $list->TableName . '.' . $list->IDField, $sql); + + $ids = ''; + $rs = $this->Conn->QueryRaw($sql); + + if ( $this->Conn->RowCount($rs) ) { + while ( ($row = $this->Conn->GetNextRow($rs)) ) { + $ids .= ',' . $row[$list->IDField]; + } + + $ids = substr($ids, 1); + } + + $this->Conn->Destroy($rs); + + return $ids; + } } \ No newline at end of file Index: core/units/languages/languages_event_handler.php =================================================================== --- core/units/languages/languages_event_handler.php (revision 15111) +++ core/units/languages/languages_event_handler.php (working copy) @@ -484,17 +484,23 @@ */ function OnExportLanguage(&$event) { - if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { + if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) { $event->status = kEvent::erFAIL; return; } - $this->Application->setUnitOption('phrases','AutoLoad',false); + $this->Application->setUnitOption('phrases', 'AutoLoad', false); $this->StoreSelectedIDs($event); - $this->Application->StoreVar('export_language_ids', implode(',', $this->getSelectedIDs($event)) ); + $this->Application->StoreVar('export_language_ids', implode(',', $this->getSelectedIDs($event))); - $event->setRedirectParams( Array('phrases.export_event' => 'OnNew', 'pass' => 'all,phrases.export') ); + $event->setRedirectParams( + Array ( + 'phrases.export_event' => 'OnNew', + 'pass' => 'all,phrases.export', + 'export_mode' => $event->Prefix, + ) + ); } /** @@ -505,17 +511,17 @@ function OnExportProgress(&$event) { $items_info = $this->Application->GetVar('phrases_export'); - if ($items_info) { + if ( $items_info ) { list($id, $field_values) = each($items_info); - $object =& $this->Application->recallObject('phrases.export', null, Array('skip_autoload' => true)); + $object =& $this->Application->recallObject('phrases.export', null, Array ('skip_autoload' => true)); /* @var $object kDBItem */ $object->setID($id); $object->SetFieldsFromHash($field_values, $this->getRequestProtectedFields($field_values)); - if (!$object->Validate()) { + if ( !$object->Validate() ) { $event->status = kEvent::erFAIL; - return ; + return; } $file_helper =& $this->Application->recallObject('FileHelper'); @@ -523,14 +529,14 @@ $file_helper->CheckFolder(EXPORT_PATH); - if (!is_writable(EXPORT_PATH)) { + if ( !is_writable(EXPORT_PATH) ) { $event->status = kEvent::erFAIL; $object->SetError('LangFile', 'write_error', 'la_ExportFolderNotWritable'); - return ; + return; } - if ( substr($field_values['LangFile'], -5) != '.lang') { + if ( substr($field_values['LangFile'], -5) != '.lang' ) { $field_values['LangFile'] .= '.lang'; } @@ -539,15 +545,23 @@ $language_import_helper =& $this->Application->recallObject('LanguageImportHelper'); /* @var $language_import_helper LanguageImportHelper */ - if ($object->GetDBField('DoNotEncode')) { + if ( $object->GetDBField('DoNotEncode') ) { $language_import_helper->setExportEncoding('plain'); } - $language_import_helper->setExportLimits($field_values['ExportPhrases'], $field_values['ExportEmailEvents']); + $export_mode = $this->Application->GetVar('export_mode'); - $lang_ids = explode(',', $this->Application->RecallVar('export_language_ids') ); + if ( $export_mode == $event->Prefix ) { + $language_import_helper->setExportLimit('phrases', $field_values['ExportPhrases']); + $language_import_helper->setExportLimit('emailevents', $field_values['ExportEmailEvents']); + } + else { + $language_import_helper->setExportLimit($export_mode); + $language_import_helper->setExportLimit($export_mode == 'phrases' ? 'emailevents' : 'phrases', '-'); + } + + $lang_ids = explode(',', $this->Application->RecallVar('export_language_ids')); $language_import_helper->performExport($filename, $field_values['PhraseType'], $lang_ids, $field_values['Module']); - } $event->redirect = 'regional/languages_export_step2'; Index: core/units/phrases/phrases_config.php =================================================================== --- core/units/phrases/phrases_config.php (revision 15111) +++ core/units/phrases/phrases_config.php (working copy) @@ -50,7 +50,7 @@ // for separate phrases list 'phrases_list_st' => Array ( 'prefixes' => Array ('phrases_List'), 'format' => "!la_title_Phrases!", - 'toolbar_buttons' => Array ('new_item', 'edit', 'delete', 'view', 'dbl-click'), + 'toolbar_buttons' => Array ('new_item', 'edit', 'delete', 'export', 'view', 'dbl-click'), ), 'phrase_edit_single' => Array ( @@ -127,7 +127,7 @@ 'LastChangeIP' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), 'Module' => Array ( 'type' => 'string', - 'formatter' => 'kOptionsFormatter', 'options' => Array ('' => ''), 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Modules WHERE (Loaded = 1) AND (Name <> "In-Portal") ORDER BY LoadOrder', 'option_key_field' => 'Name', 'option_title_field' => 'Name', + 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Modules WHERE (Loaded = 1) AND (Name <> "In-Portal") ORDER BY LoadOrder', 'option_key_field' => 'Name', 'option_title_field' => 'Name', 'not_null' => 1, 'required' => 1, 'default' => 'Core' ), ), @@ -182,7 +182,7 @@ 'PrimaryTranslation' => Array ('title' => 'la_col_PrimaryValue', 'width' => 200), 'PhraseType' => Array ('filter_block' => 'grid_options_filter', 'width' => 60), 'LastChanged' => Array ('title' => 'column:la_fld_Modified', 'filter_block' => 'grid_date_range_filter', 'width' => 150), - 'Module' => Array ('filter_block' => 'grid_options_filter', 'width' => 100), + 'Module' => Array ('filter_block' => 'grid_multioptions_filter', 'width' => 100), 'CurrentHintTranslation' => Array ('title' => 'la_col_HintPhrase', 'width' => 200, 'hidden' => 1), 'CurrentColumnTranslation' => Array ('title' => 'la_col_ColumnPhrase', 'width' => 200, 'hidden' => 1), ), @@ -199,9 +199,9 @@ 'PhraseId' => Array ('title' => 'column:la_fld_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'width' => 50), 'Phrase' => Array ('title' => 'la_col_Label', 'filter_block' => 'grid_like_filter', 'width' => 170), 'CurrentTranslation' => Array ('title' => 'column:la_fld_Phrase', 'filter_block' => 'grid_like_filter', 'width' => 180), - 'PhraseType' => Array ('title' => 'column:la_fld_Location', 'filter_block' => 'grid_options_filter', 'width' => 80), + 'PhraseType' => Array ('title' => 'column:la_fld_Location', 'filter_block' => 'grid_multioptions_filter', 'width' => 80), 'LastChanged' => Array ('title' => 'column:la_fld_Modified', 'filter_block' => 'grid_date_range_filter', 'width' => 145), - 'Module' => Array ('filter_block' => 'grid_options_filter', 'width' => 100), + 'Module' => Array ('filter_block' => 'grid_multioptions_filter', 'width' => 100), 'CurrentHintTranslation' => Array ('title' => 'la_col_HintPhrase', 'width' => 200, 'hidden' => 1), 'CurrentColumnTranslation' => Array ('title' => 'la_col_ColumnPhrase', 'width' => 200, 'hidden' => 1), ), Index: core/units/phrases/phrases_event_handler.php =================================================================== --- core/units/phrases/phrases_event_handler.php (revision 15111) +++ core/units/phrases/phrases_event_handler.php (working copy) @@ -17,6 +17,26 @@ class PhrasesEventHandler extends kDBEventHandler { /** + * Allows to override standard permission mapping + * + * @return void + * @access protected + * @see kEventHandler::$permMapping + */ + protected function mapPermissions() + { + parent::mapPermissions(); + + $permissions = Array ( + 'OnItemBuild' => Array ('self' => true, 'subitem' => true), + 'OnPreparePhrase' => Array ('self' => true, 'subitem' => true), + 'OnExportPhrases' => Array ('self' => 'view'), + ); + + $this->permMapping = array_merge($this->permMapping, $permissions); + } + + /** * Apply some special processing to object being * recalled before using it in other events that * call prepareObject @@ -59,25 +79,6 @@ } /** - * Allows to override standard permission mapping - * - * @return void - * @access protected - * @see kEventHandler::$permMapping - */ - protected function mapPermissions() - { - parent::mapPermissions(); - - $permissions = Array ( - 'OnItemBuild' => Array('self' => true, 'subitem' => true), - 'OnPreparePhrase' => Array('self' => true, 'subitem' => true), - ); - - $this->permMapping = array_merge($this->permMapping, $permissions); - } - - /** * Prepares phrase for translation * * @param kEvent $event @@ -465,4 +466,32 @@ // use language from grid, instead of primary language used by default $event->SetRedirectParam('m_lang', $this->Application->GetVar('m_lang')); } + + /** + * Stores ids of selected phrases and redirects to export language step 1 + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnExportPhrases(kEvent &$event) + { + if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) { + $event->status = kEvent::erFAIL; + return; + } + + $this->Application->setUnitOption('phrases', 'AutoLoad', false); + + $this->StoreSelectedIDs($event); + $this->Application->StoreVar('export_language_ids', $this->Application->GetVar('m_lang')); + + $event->setRedirectParams( + Array ( + 'phrases.export_event' => 'OnNew', + 'pass' => 'all,phrases.export', + 'export_mode' => $event->Prefix, + ) + ); + } } \ No newline at end of file
- id="_" value="" onclick="update_checkbox_options(/^_([0-9A-Za-z-]+)/, '');"/> - - - - - - -
+ id="_" value="" onclick="update_checkbox_options(/^_([0-9A-Za-z-]+)/, '');"/> + + + + + + +
- - -

+ +
+ + +

- + table#modules td, table#modules th { + border: 1px solid black; + padding: 3px; + } + - - - - - - - -
+ + + + + + + +
- + $("input[type='checkbox']", '#modules').attr('checked', $checked); + update_checkbox_options($reg_exp, ''); + } + ); + } + ); + - -