diff --git a/README.md b/README.md index a6fd629b..34b33ad2 100644 --- a/README.md +++ b/README.md @@ -27,11 +27,8 @@ master - latest stable version (1.x) develop - latest development version (1.x) - master_09 - latest stable version 0.9.x -dvelum_2.0 - development of version 2.x - - - +----- +Dvelum 2.0 repository: https://github.com/dvelum/dvelum diff --git a/application/configs/dist/media_library.php b/application/configs/dist/media_library.php index 696c275a..073c0a80 100755 --- a/application/configs/dist/media_library.php +++ b/application/configs/dist/media_library.php @@ -2,6 +2,9 @@ 'image' => array ( 'title' => 'Images', + // 15 mb + 'max_file_size'=> 1024*1024*1024*15, + 'rewrite'=>false, 'extensions' => array ( 0 => '.gif', diff --git a/application/configs/dist/objects/medialib.php b/application/configs/dist/objects/medialib.php index c7350e1a..06131ffc 100755 --- a/application/configs/dist/objects/medialib.php +++ b/application/configs/dist/objects/medialib.php @@ -163,6 +163,19 @@ 'db_default' => false, 'db_unsigned' => true, ), + 'hash' => + array ( + 'type' => '', + 'unique' => '', + 'db_isNull' => true, + 'required' => false, + 'validator' => '', + 'db_type' => 'varchar', + 'db_default' => '', + 'db_len' => 255, + 'is_search' => true, + 'allow_html' => false, + ), ), 'indexes' => array ( @@ -185,6 +198,15 @@ 0 => 'title', ), ), + 'hash' => + array ( + 'fulltext' => false, + 'unique' => false, + 'columns' => + array ( + 0 => 'hash', + ), + ), ), 'connection' => 'default', 'locked' => false, diff --git a/application/configs/dist/versions.php b/application/configs/dist/versions.php index 9b5f4cd3..9a4b848f 100644 --- a/application/configs/dist/versions.php +++ b/application/configs/dist/versions.php @@ -1,7 +1,7 @@ '1.0.1', + 'core'=>'1.0.2', 'designer'=>'1.1', - 'medialib'=>'0.5', + 'medialib'=>'0.6', 'orm'=>'0.9.9' ); \ No newline at end of file diff --git a/application/locales/dist/_index.php b/application/locales/dist/_index.php index 0b1610be..0c0f4ce8 100644 --- a/application/locales/dist/_index.php +++ b/application/locales/dist/_index.php @@ -577,4 +577,5 @@ 577 => 'FILTER_OBJECTS', 578 => 'USER_PERMISSIONS', 579 => 'PERMISSIONS', + 580 => 'PAGECODE_MATCH' ); \ No newline at end of file diff --git a/application/locales/dist/en.php b/application/locales/dist/en.php index 32eb1e3b..50093adb 100644 --- a/application/locales/dist/en.php +++ b/application/locales/dist/en.php @@ -578,4 +578,5 @@ 'FILTER_OBJECTS' => 'Filter objects', 'USER_PERMISSIONS' => 'User permissions', 'PERMISSIONS' => 'Permissions', + 'PAGECODE_MATCH' => 'This field should only contain letters, numbers and _ -' ); diff --git a/application/locales/dist/en/objects.php b/application/locales/dist/en/objects.php index 8f442e62..0b865dfa 100644 --- a/application/locales/dist/en/objects.php +++ b/application/locales/dist/en/objects.php @@ -119,6 +119,7 @@ 'modified' => 'Date modified', 'croped' => 'Is Croped', 'category' => 'Category', + 'hash'=>'File hash' ), ), 'menu_item' => diff --git a/application/locales/dist/ru.php b/application/locales/dist/ru.php index 783cdaf9..e62677f6 100644 --- a/application/locales/dist/ru.php +++ b/application/locales/dist/ru.php @@ -580,4 +580,5 @@ 'FILTER_OBJECTS' => 'Выбрать объекты', 'USER_PERMISSIONS' => 'Права пользователей', 'PERMISSIONS' => 'Права доступа', + 'PAGECODE_MATCH' => 'Это моле может содержать только цифры, латински буквы и символы _ -' ); diff --git a/application/locales/dist/ru/import.php b/application/locales/dist/ru/import.php index d88a3e20..06d1b779 100644 --- a/application/locales/dist/ru/import.php +++ b/application/locales/dist/ru/import.php @@ -9,10 +9,10 @@ 'IMPORT' => 'Импорт', 'IMPORT_COMPLETED' => 'Импорт успешно завершен', 'EXPECTED_COLUMNS' => 'Ожидаемые колонки', - 'UNSUPPORTED_FORMAT' => 'Unsupported file type. Please upload .xls or .csv file', + 'UNSUPPORTED_FORMAT' => 'Неподдерживаемый формат файла. Загрузите .xls, xlsx или .csv файл', 'FILL_CORRECTLY' => 'Необходимо верно заполнить форму', 'click_column' => 'Кликните по заголовку таблицы, чтобы указать колонку.', - 'click_first_row' => 'Кликните 2 раза на строке чтобы указать начало данных.', + 'click_first_row' => 'Кликните 2 раза на строке, чтобы указать начало данных.', 'expected_columns' => 'Ожидаемые колонки', 'required_fields' => 'Ввод информации со звездочкой обязателен *', 'import' => 'Импортировать', diff --git a/application/locales/dist/ru/objects.php b/application/locales/dist/ru/objects.php index f3e7837c..e64df6b2 100644 --- a/application/locales/dist/ru/objects.php +++ b/application/locales/dist/ru/objects.php @@ -101,6 +101,7 @@ 'modified' => 'Дата модификации', 'croped' => 'Обрезан вручную', 'category' => 'Каталог', + 'hash' => 'Хэш файла' ), ), 'menu_item' => diff --git a/data/gpl-3.0_en.txt b/data/gpl-3.0_en.txt index e8d4b121..97168d3c 100644 --- a/data/gpl-3.0_en.txt +++ b/data/gpl-3.0_en.txt @@ -1,5 +1,5 @@ -DVelum 1.0.1 PROFESSIONAL WEB-DEVELOPMENT PLATFORM -Copyright (C) 2011-2016, Kirill A Egorov, Andrew Zamotaev, Sergey Leschenko +DVelum 1.0.2 PROFESSIONAL WEB-DEVELOPMENT PLATFORM +Copyright (C) 2011-2017, Kirill A Egorov, Andrew Zamotaev, Sergey Leschenko http://dvelum.net/license.html This version of DVelum is licensed under the terms of the Open Source GPL 3.0 license. diff --git a/data/gpl-3.0_ru.txt b/data/gpl-3.0_ru.txt index 47edc43f..e31edd74 100644 --- a/data/gpl-3.0_ru.txt +++ b/data/gpl-3.0_ru.txt @@ -1,5 +1,5 @@ -DVelum 1.0.1 платформа профессиональной web-разработки -Copyright (C) 2011-2016 Кирилл Егоров, Андрей Замотаев, Сергей Лещенко +DVelum 1.0.2 платформа профессиональной web-разработки +Copyright (C) 2011-2017 Кирилл Егоров, Андрей Замотаев, Сергей Лещенко Данная версия DVelum лицензируется на условиях универсальной общественной лицензии GNU GPL 3.0. diff --git a/dvelum/app/Backend/Controller/Crud.php b/dvelum/app/Backend/Controller/Crud.php index 1b40d628..81828c96 100644 --- a/dvelum/app/Backend/Controller/Crud.php +++ b/dvelum/app/Backend/Controller/Crud.php @@ -48,6 +48,8 @@ abstract class Backend_Controller_Crud extends Backend_Controller */ protected $_listLinks = []; + protected $_linkedInfoSeparator = '; '; + public function __construct() { parent::__construct(); @@ -307,7 +309,7 @@ public function updateObject(Db_Object $object) /** * Get list of objects which can be linked */ - public function linkedlistAction() + protected function getRelatedObjectsInfo() { $object = Request::post('object', 'string', false); $filter = Request::post('filter' , 'array' , []); @@ -319,7 +321,7 @@ public function linkedlistAction() Response::jsonError($this->_lang->WRONG_REQUEST); if(!in_array(strtolower($object), $this->_canViewObjects , true)) - Response::jsonError($this->_lang->CANT_VIEW); + Response::jsonError($this->_lang->CANT_VIEW); $objectCfg = Db_Object_Config::getInstance($object); $primaryKey = $objectCfg->getPrimaryKey(); @@ -347,7 +349,7 @@ public function linkedlistAction() $data = array(); if($count) { - $data = $model->getList($pager, $filter, $fields , false , $query); + $data = $model->getList($pager, $filter, $fields , false , $query); if(!empty($data)) { @@ -379,12 +381,26 @@ public function linkedlistAction() }unset($item); } } - Response::jsonSuccess($data,array('count'=>$count)); + return ['data'=>$data,'count'=>$count]; + } + + /** + * Get list of objects which can be linked + */ + public function linkedListAction() + { + $result = $this->getRelatedObjectsInfo(); + + if(empty($result)){ + Response::jsonSuccess([]); + }else{ + Response::jsonArray($result); + } } /** * Get object title */ - public function otitleAction() + public function objectTitleAction() { $object = Request::post('object','string', false); $id = Request::post('id', 'string', false); @@ -410,9 +426,17 @@ public function otitleAction() }catch (Exception $e){ Model::factory($object)->logError('Cannot get title for '.$object.':'.$id); Response::jsonError($this->_lang->get('CANT_EXEC')); - } + }; } + /** + * Get object title + * @deprecated + */ + public function otitleAction() + { + $this->objectTitleAction(); + } /** * Add related objects info into getList results @@ -522,7 +546,7 @@ protected function addLinkedInfo(Db_Object_Config $cfg, array $fieldsToShow, arr } } } - $row[$fieldsToKeys[$field]] = implode(', ', $list); + $row[$fieldsToKeys[$field]] = implode($this->_linkedInfoSeparator, $list); } }unset($row); } diff --git a/dvelum/app/Backend/Designer/Sub/Code.php b/dvelum/app/Backend/Designer/Sub/Code.php index 828a9783..3104f5a2 100644 --- a/dvelum/app/Backend/Designer/Sub/Code.php +++ b/dvelum/app/Backend/Designer/Sub/Code.php @@ -1,65 +1,65 @@ _getProject(); + /** + * Get JS code for object + */ + public function objectcodeAction() + { + $object = Request::post('object' , 'string' , ''); + $project = $this->_getProject(); - if(! $project->objectExists($object)) - Response::jsonError($this->_lang->WRONG_REQUEST); + if(! $project->objectExists($object)) + Response::jsonError($this->_lang->WRONG_REQUEST); - $projectCfg = $project->getConfig(); - Ext_Code::setRunNamespace($projectCfg['runnamespace']); - Ext_Code::setNamespace($projectCfg['namespace']); + $projectCfg = $project->getConfig(); + Ext_Code::setRunNamespace($projectCfg['runnamespace']); + Ext_Code::setNamespace($projectCfg['namespace']); - $templates = $this->_config->get('templates'); - $replaces = array( - array( - 'tpl' => $templates['wwwroot'] , - 'value' => $this->_configMain->get('wwwroot') - ) , - array( - 'tpl' => $templates['adminpath'] , - 'value' => $this->_configMain->get('adminPath') - ) , - array( - 'tpl' => $templates['urldelimiter'] , - 'value' => $this->_configMain->get('urlDelimiter') - ) - ); + $templates = $this->_config->get('templates'); + $replaces = array( + array( + 'tpl' => $templates['wwwroot'] , + 'value' => $this->_configMain->get('wwwroot') + ) , + array( + 'tpl' => $templates['adminpath'] , + 'value' => $this->_configMain->get('adminPath') + ) , + array( + 'tpl' => $templates['urldelimiter'] , + 'value' => $this->_configMain->get('urlDelimiter') + ) + ); - $code = $project->getObjectCode($object , $replaces); - Response::jsonSuccess($code); - } + $code = $project->getObjectCode($object , $replaces); + Response::jsonSuccess($code); + } - /** - * Get JS code for project - */ - public function projectcodeAction() - { - $project = $this->_getProject(); - $projectCfg = $project->getConfig(); - $templates = $this->_config->get('templates'); - $replaces = array( + /** + * Get JS code for project + */ + public function projectcodeAction() + { + $project = $this->_getProject(); + $projectCfg = $project->getConfig(); + $templates = $this->_config->get('templates'); + $replaces = array( array( - 'tpl' => $templates['wwwroot'] , - 'value' => $this->_configMain->get('wwwroot') + 'tpl' => $templates['wwwroot'] , + 'value' => $this->_configMain->get('wwwroot') ) , array( - 'tpl' => $templates['adminpath'] , - 'value' => $this->_configMain->get('adminPath') + 'tpl' => $templates['adminpath'] , + 'value' => $this->_configMain->get('adminPath') ) , array( - 'tpl' => $templates['urldelimiter'] , - 'value' => $this->_configMain->get('urlDelimiter') + 'tpl' => $templates['urldelimiter'] , + 'value' => $this->_configMain->get('urlDelimiter') ) - ); - Ext_Code::setRunNamespace($projectCfg['runnamespace']); - Ext_Code::setNamespace($projectCfg['namespace']); - Response::jsonSuccess($project->getCode($replaces)); - } + ); + Ext_Code::setRunNamespace($projectCfg['runnamespace']); + Ext_Code::setNamespace($projectCfg['namespace']); + Response::jsonSuccess($project->getCode($replaces)); + } } \ No newline at end of file diff --git a/dvelum/app/Backend/Designer/Sub/Events.php b/dvelum/app/Backend/Designer/Sub/Events.php index b560d744..28be7073 100644 --- a/dvelum/app/Backend/Designer/Sub/Events.php +++ b/dvelum/app/Backend/Designer/Sub/Events.php @@ -1,324 +1,315 @@ _getProject(); - $eventManager = $project->getEventManager(); - $list = $eventManager->getEvents(); - - - //echo '
'; print_r($list);
-		$result = array();
-
-		foreach ($list as $o=>$e)
-		{
-			if(empty($e))
-				continue;
-
-			if($project->objectExists($o))
-			{
-
-			    $object = $project->getObject($o);
-				/*
-				 * Real project object
-				 */
-			    if($object->isInstance()){
-				    $events = $object->getObject()->getConfig()->getEvents()->__toArray();
-			    }else{
-			        $events = $object->getConfig()->getEvents()->__toArray();
-			    }
-
-				foreach ($e as $eName=>$eConfig)
-				{
-					if(isset($events[$eName]))
-						$eConfig['params'] = $this->_convertParams($events[$eName]);
-					else
-						$eConfig['params'] = '';
-
-					unset($eConfig['code']);
-					$eConfig['is_local'] = true;
-					$result[] = $eConfig;
-
-				}
-			}
-			else
-			{
-				/*
-				 * Sub items with events
-				 */
-				foreach ($e as $eName=>$eConfig)
-				{
-					if(isset($eConfig['params']) && is_array($eConfig['params']))
-						$eConfig['params'] = $this->_convertParams($eConfig['params']);
-					else
-						$eConfig['params'] = '';
-
-					unset($eConfig['code']);
-					$eConfig['is_local'] = true;
-					$result[] = $eConfig;
-				}
-			}
-		}
-      //  print_r($result); die();
+    /**
+     * Get all registered events
+     */
+    public function listAction()
+    {
+        $project = $this->_getProject();
+        $eventManager = $project->getEventManager();
+        $list = $eventManager->getEvents();
+
+        $result = array();
+
+        foreach ($list as $o=>$e)
+        {
+            if(empty($e))
+                continue;
+
+            if($project->objectExists($o))
+            {
+                $object = $project->getObject($o);
+                $eventObject = $object;
+
+                while (method_exists($eventObject, 'getObject')){
+                    $eventObject = $eventObject->getObject();
+                }
+
+                $events = $eventObject->getConfig()->getEvents()->__toArray();
+
+
+                foreach ($e as $eName=>$eConfig)
+                {
+                    if(isset($events[$eName]))
+                        $eConfig['params'] = $this->_convertParams($events[$eName]);
+                    else
+                        $eConfig['params'] = '';
+
+                    unset($eConfig['code']);
+                    $eConfig['is_local'] = true;
+                    $result[] = $eConfig;
+
+                }
+            }
+            else
+            {
+                /*
+                 * Sub items with events
+                 */
+                foreach ($e as $eName=>$eConfig)
+                {
+                    if(isset($eConfig['params']) && is_array($eConfig['params']))
+                        $eConfig['params'] = $this->_convertParams($eConfig['params']);
+                    else
+                        $eConfig['params'] = '';
+
+                    unset($eConfig['code']);
+                    $eConfig['is_local'] = true;
+                    $result[] = $eConfig;
+                }
+            }
+        }
         Response::jsonSuccess($result);
-	}
-	protected function _convertParams($config)
-	{
-		if(empty($config))
-			return '';
-
-		foreach ($config as $pName=>$pType)
-			$paramsArray[] = '' . $pType . ' ' . $pName;
-
-		return implode(' , ', $paramsArray);
-	}
-
-	/**
-	 * Get events for object
-	 */
-	public function objecteventsAction()
-	{
-		$project = $this->_getProject();
-
-		$name = Request::post('object', 'string', '');
-
-		if(!strlen($name) || !$project->objectExists($name))
-		    Response::jsonSuccess(array());
-
-		$object = $project->getObject($name);
-
-		$objectName = $object->getName();
-
-		$objectEvents = $project->getEventManager()->getObjectEvents($objectName);
-
-		if($object->isInstance()){
-		  $events = $object->getObject()->getConfig()->getEvents();
-		}else{
-		  $events = $object->getConfig()->getEvents();
-		}
-
-		$result = array();
-		$id =1;
-		foreach ($events as $name=>$config)
-		{
-			if(isset($objectEvents[$name]) && !empty($objectEvents[$name]))
-				$hasCode = true;
-			else
-				$hasCode = false;
-
-			$result[$name] = array(
-				'id'=>$id,
-				'object'=>$objectName,
-				'event'=>$name,
-				'params'=>$this->_convertParams($config),
-				'has_code'=>$hasCode,
-			    'is_local'=>false
-			);
-			$id++;
-		}
-
-		$localEvents = $project->getEventManager()->getLocalEvents($objectName);
-		foreach ($localEvents as $name => $description)
-		{
-		  if(isset($result[$name]))
-		    continue;
-
-		  $result[$name] = array(
-              'id'=>$name,
-              'object'=>$objectName,
-              'event'=>$name,
-              'params'=>$this->_convertParams($description['params']),
-              'has_code'=>!empty($description['code']),
-              'is_local'=>true
-		  );
-
-		}
-		Response::jsonSuccess(array_values($result));
-	}
-
-  protected function _getEvent()
-  {
-    $event = Request::post('event' , 'string' , false);
-    if(!strlen($event) || $event === false)
-      Response::jsonError($this->_lang->WRONG_REQUEST);
-    return $event;
-  }
-
-  /**
-   * Load event description
-   */
-  public function eventcodeAction()
-  {
-    $objectName = Request::post('object' , 'string' , '');
-    $project = $this->_getProject();
-
-    if(!strlen($objectName))
-      Response::jsonError($this->_lang->WRONG_REQUEST);
-
-    $event = $this->_getEvent();
-
-    $eventManager = $project->getEventManager();
-
-    if($eventManager->eventExists($objectName , $event))
-      $info = $eventManager->getEventInfo($objectName , $event);
-    else
-      $info = array('code'=>'');
-
-    if(isset($info['params']))
-      $info['params'] = strip_tags($this->_convertParams($info['params']));
-    else
-      $info['params'] = '';
-
-    Response::jsonSuccess($info);
-  }
-
-  /**
-   * Update event description
-   */
-  public function saveeventAction()
-  {
-    $project = $this->_getProject();
-
-
-    $name = Request::post('object', 'string', '');
-
-    if(!strlen($name))
-        Response::jsonError($this->_lang->WRONG_REQUEST);
-
-    if($project->objectExists($name))
-      $object = $project->getObject($name);
-    else
-      $object = false;
-
-    $event = $this->_getEvent();
-
-    $eventManager = $project->getEventManager();
-    if($object && $eventManager->isLocalEvent($object->getName() , $event))
+    }
+    protected function _convertParams($config)
+    {
+        if(empty($config))
+            return '';
+
+        foreach ($config as $pName=>$pType)
+            $paramsArray[] = '' . $pType . ' ' . $pName;
+
+        return implode(' , ', $paramsArray);
+    }
+
+
+    /**
+     * Get events for object
+     */
+    public function objecteventsAction()
     {
-      $newName = Request::post('new_name' , Filter::FILTER_ALPHANUM , '');
+        $project = $this->_getProject();
+        $object = $this->_getObject();
+
+        $objectName = $object->getName();
 
-      if(!strlen($newName))
-        Response::jsonError($this->_lang->get('FILL_FORM') , array('new_name'=>$this->_lang->get('CANT_BE_EMPTY')));
+        $objectEvents = $project->getEventManager()->getObjectEvents($objectName);
 
-      $params = Request::post('params', Filter::FILTER_STRING, '');
-      $code = Request::post('code', Filter::FILTER_RAW, '');
+        if($object->isInstance()){
+            $events = $object->getObject()->getConfig()->getEvents();
+        }else{
+            $events = $object->getConfig()->getEvents();
+        }
 
-      if(!$eventManager->eventExists($object->getName(), $event))
-          Response::jsonError($this->_lang->WRONG_REQUEST);
+        $result = array();
+        $id =1;
+        foreach ($events as $name=>$config)
+        {
+            if(isset($objectEvents[$name]) && !empty($objectEvents[$name]))
+                $hasCode = true;
+            else
+                $hasCode = false;
+
+            $result[$name] = array(
+                'id'=>$id,
+                'object'=>$objectName,
+                'event'=>$name,
+                'params'=>$this->_convertParams($config),
+                'has_code'=>$hasCode,
+                'is_local'=>false
+            );
+            $id++;
+        }
 
-      if(!empty($params))
-      {
-        $params = explode(',' , trim($params));
-        $paramsArray = array();
-        foreach ($params as $k=>$v)
+        $localEvents = $project->getEventManager()->getLocalEvents($objectName);
+        foreach ($localEvents as $name => $description)
         {
-          $param = explode(' ', trim($v));
-          if(count($param) == 1)
-          {
-            $paramsArray[trim($v)] = '';
-          }else{
-            $pName = array_pop($param);
-            $ptype = trim(implode(' ', str_replace('  ', ' ',$param)));
-            $paramsArray[$pName] = $ptype;
-          }
+            if(isset($result[$name]))
+                continue;
+
+            $result[$name] = array(
+                'id'=>$name,
+                'object'=>$objectName,
+                'event'=>$name,
+                'params'=>$this->_convertParams($description['params']),
+                'has_code'=>!empty($description['code']),
+                'is_local'=>true
+            );
+
         }
-        $params = $paramsArray;
-      }
-      $eventManager->setEvent($object->getName(), $event, $code , $params , true);
-
-      if($newName!==$event)
-      {
-        if($eventManager->eventExists($object, $newName) || $object->getConfig()->getEvents()->isValid($newName))
-          Response::jsonError($this->_lang->get('FILL_FORM') , array('new_name'=>$this->_lang->get('SB_UNIQUE')));
-
-        $eventManager->renameLocalEvent($object->getName() , $event , $newName);
-      }
-      $this->_storeProject();
-      Response::jsonSuccess();
+        Response::jsonSuccess(array_values($result));
     }
-    else
+
+    protected function _getEvent()
     {
-      // update event action for std event
-     $this->setcodeAction();
+        $event = Request::post('event' , 'string' , false);
+        if(!strlen($event) || $event === false)
+            Response::jsonError($this->_lang->WRONG_REQUEST);
+        return $event;
     }
-  }
 
-  public function setcodeAction()
-  {
-    $objectName = Request::post('object' , 'string' , '');
-    $project = $this->_getProject();
+    /**
+     * Load event description
+     */
+    public function eventcodeAction()
+    {
+        $objectName = Request::post('object' , 'string' , '');
+        $project = $this->_getProject();
+
+        if(!strlen($objectName))
+            Response::jsonError($this->_lang->WRONG_REQUEST);
+
+        $event = $this->_getEvent();
 
-    if(!strlen($objectName))
-      Response::jsonError($this->_lang->WRONG_REQUEST);
+        $eventManager = $project->getEventManager();
 
-    $event = $this->_getEvent();
-    $code = Request::post('code' , 'raw' , '');
+        if($eventManager->eventExists($objectName , $event))
+            $info = $eventManager->getEventInfo($objectName , $event);
+        else
+            $info = array('code'=>'');
 
-    $project->getEventManager()->setEvent($objectName , $event , $code);
-    $this->_storeProject();
-    Response::jsonSuccess();
-  }
+        if(isset($info['params']))
+            $info['params'] = strip_tags($this->_convertParams($info['params']));
+        else
+            $info['params'] = '';
+
+        Response::jsonSuccess($info);
+    }
+
+    /**
+     * Update event description
+     */
+    public function saveeventAction()
+    {
+        $project = $this->_getProject();
 
-  public function removeeventAction()
-  {
-    $project = $this->_getProject();
-    $event = $this->_getEvent();
-    $object = Request::post('object' , 'string' , '');
 
-    if(!strlen($object))
-      Response::jsonError($this->_lang->WRONG_REQUEST);
+        $name = Request::post('object', 'string', '');
 
-    $eventManager = $project->getEventManager();
+        if(!strlen($name))
+            Response::jsonError($this->_lang->WRONG_REQUEST);
 
-    if($eventManager->isLocalEvent($object, $event)){
-      $eventManager->updateEvent($object, $event, '');
-    }else{
-      $eventManager->removeObjectEvent($object , $event);
+        if($project->objectExists($name))
+            $object = $this->_getObject();
+        else
+            $object = false;
+
+        $event = $this->_getEvent();
+
+        $eventManager = $project->getEventManager();
+        if($object && $eventManager->isLocalEvent($object->getName() , $event))
+        {
+            $newName = Request::post('new_name' , Filter::FILTER_ALPHANUM , '');
+
+            if(!strlen($newName))
+                Response::jsonError($this->_lang->get('FILL_FORM') , array('new_name'=>$this->_lang->get('CANT_BE_EMPTY')));
+
+            $params = Request::post('params', Filter::FILTER_STRING, '');
+            $code = Request::post('code', Filter::FILTER_RAW, '');
+
+            if(!$eventManager->eventExists($object->getName(), $event))
+                Response::jsonError($this->_lang->WRONG_REQUEST);
+
+            if(!empty($params))
+            {
+                $params = explode(',' , trim($params));
+                $paramsArray = array();
+                foreach ($params as $k=>$v)
+                {
+                    $param = explode(' ', trim($v));
+                    if(count($param) == 1)
+                    {
+                        $paramsArray[trim($v)] = '';
+                    }else{
+                        $pName = array_pop($param);
+                        $ptype = trim(implode(' ', str_replace('  ', ' ',$param)));
+                        $paramsArray[$pName] = $ptype;
+                    }
+                }
+                $params = $paramsArray;
+            }
+            $eventManager->setEvent($object->getName(), $event, $code , $params , true);
+
+            if($newName!==$event)
+            {
+                if($eventManager->eventExists($object, $newName) || $object->getConfig()->getEvents()->isValid($newName))
+                    Response::jsonError($this->_lang->get('FILL_FORM') , array('new_name'=>$this->_lang->get('SB_UNIQUE')));
+
+                $eventManager->renameLocalEvent($object->getName() , $event , $newName);
+            }
+            $this->_storeProject();
+            Response::jsonSuccess();
+        }
+        else
+        {
+            // update event action for std event
+            $this->setcodeAction();
+        }
     }
-    $this->_storeProject();
-    Response::jsonSuccess();
-  }
-
-  /**
-   * Remove local event
-   */
-  public function removeeventdescriptionAction()
-  {
-    $project = $this->_getProject();
-    $event = $this->_getEvent();
-
-    $object = Request::post('object' , 'string' , '');
-
-    if(!strlen($object))
-        Response::jsonError($this->_lang->WRONG_REQUEST);
-
-    $eventManager = $project->getEventManager();
-    $eventManager->removeObjectEvent($object , $event);
-    $this->_storeProject();
-    Response::jsonSuccess();
-  }
-
-  /**
-   * Create local event fore extended object
-   */
-  public function addlocaleventAction()
-  {
-    $project = $this->_getProject();
-    $event = Filter::filterValue(Filter::FILTER_ALPHANUM, $this->_getEvent());
-    $object = $this->_getObject();
-
-    $eventManager = $project->getEventManager();
-
-    if($eventManager->eventExists($object->getName(), $event) || $object->getConfig()->getEvents()->isValid($event)){
-        Response::jsonError($this->_lang->get('SB_UNIQUE'));
+
+    public function setcodeAction()
+    {
+        $objectName = Request::post('object' , 'string' , '');
+        $project = $this->_getProject();
+
+        if(!strlen($objectName))
+            Response::jsonError($this->_lang->WRONG_REQUEST);
+
+        $event = $this->_getEvent();
+        $code = Request::post('code' , 'raw' , '');
+
+        $project->getEventManager()->setEvent($objectName , $event , $code);
+        $this->_storeProject();
+        Response::jsonSuccess();
     }
 
-    $eventManager->setEvent($object->getName(), $event, '' , '' , true);
-    $this->_storeProject();
-    Response::jsonSuccess();
-  }
+    public function removeeventAction()
+    {
+        $project = $this->_getProject();
+        $event = $this->_getEvent();
+        $object = Request::post('object' , 'string' , '');
+
+        if(!strlen($object))
+            Response::jsonError($this->_lang->WRONG_REQUEST);
+
+        $eventManager = $project->getEventManager();
+
+        if($eventManager->isLocalEvent($object, $event)){
+            $eventManager->updateEvent($object, $event, '');
+        }else{
+            $eventManager->removeObjectEvent($object , $event);
+        }
+        $this->_storeProject();
+        Response::jsonSuccess();
+    }
+
+    /**
+     * Remove local event
+     */
+    public function removeeventdescriptionAction()
+    {
+        $project = $this->_getProject();
+        $event = $this->_getEvent();
+
+        $object = Request::post('object' , 'string' , '');
+
+        if(!strlen($object))
+            Response::jsonError($this->_lang->WRONG_REQUEST);
+
+        $eventManager = $project->getEventManager();
+        $eventManager->removeObjectEvent($object , $event);
+        $this->_storeProject();
+        Response::jsonSuccess();
+    }
+
+    /**
+     * Create local event fore extended object
+     */
+    public function addlocaleventAction()
+    {
+        $project = $this->_getProject();
+        $event = Filter::filterValue(Filter::FILTER_ALPHANUM, $this->_getEvent());
+        $object = $this->_getObject();
+
+        $eventManager = $project->getEventManager();
+
+        if($eventManager->eventExists($object->getName(), $event) || $object->getConfig()->getEvents()->isValid($event)){
+            Response::jsonError($this->_lang->get('SB_UNIQUE'));
+        }
+
+        $eventManager->setEvent($object->getName(), $event, '' , '' , true);
+        $this->_storeProject();
+        Response::jsonSuccess();
+    }
 }
diff --git a/dvelum/app/Backend/Designer/Sub/Filterevents.php b/dvelum/app/Backend/Designer/Sub/Filterevents.php
new file mode 100644
index 00000000..f3659c85
--- /dev/null
+++ b/dvelum/app/Backend/Designer/Sub/Filterevents.php
@@ -0,0 +1,9 @@
+getViewObject();
+    }
+}
\ No newline at end of file
diff --git a/dvelum/app/Backend/Designer/Sub/Objects.php b/dvelum/app/Backend/Designer/Sub/Objects.php
index 76a5878b..11b5be52 100644
--- a/dvelum/app/Backend/Designer/Sub/Objects.php
+++ b/dvelum/app/Backend/Designer/Sub/Objects.php
@@ -206,6 +206,7 @@ static public function getIconClass($objClass)
             'Form_Checkboxgroup'=>'checkboxGroupIcon',
             'Form_Radiogroup'=>'radioGroupIcon',
             'Form_Field_Combobox'=>'comboboxFieldIcon',
+            'Form_Field_Tag'=>'tagIcon',
 
             'Button'=>'buttonIcon',
             'Button_Split'=>'buttonSplitIcon',
diff --git a/dvelum/app/Backend/Designer/Sub/Store.php b/dvelum/app/Backend/Designer/Sub/Store.php
index 400f7ceb..dfb253b5 100644
--- a/dvelum/app/Backend/Designer/Sub/Store.php
+++ b/dvelum/app/Backend/Designer/Sub/Store.php
@@ -77,7 +77,7 @@ public function storeFieldsAction()
         Response::jsonSuccess($fields);
     }
     /**
-     * Get list of store fields, include fields from model
+     * Get list of store fields
      */
     public function listfieldsAction()
     {
@@ -96,12 +96,13 @@ public function listfieldsAction()
             $this->_object = $this->_object->getObject();
         $fields = array();
 
-        $model = $this->_object->model;
-
-        if(strlen($model)){
-            $model = $this->_project->getObject($model);
-            $fields = $model->fields;
-        }
+         // Do not show model fields. It cause misleading
+//        $model = $this->_object->model;
+//
+//        if(strlen($model)){
+//            $model = $this->_project->getObject($model);
+//            $fields = $model->fields;
+//        }
 
         if(empty($fields))
             $fields = $this->_object->fields;
@@ -122,40 +123,50 @@ public function allfieldsAction()
         $this->_checkLoaded();
         $name = Request::post('object', 'string', '');
 
+        $name = trim(str_replace('[new:]','',$name));
+
         $project = $this->_getProject();
         if(!strlen($name) || !$project->objectExists($name))
             Response::jsonError('Undefined Store object');
 
         $this->_project = $project;
         $this->_object = $project->getObject($name);
+
         if($this->_object->isInstance())
             $this->_object = $this->_object->getObject();
-        $fields = array();
 
-        if($this->_object->isValidProperty('model') && strlen($this->_object->model) && $this->_project->objectExists($this->_object->model))
-        {
-            $model = $this->_project->getObject($this->_object->model);
+        $fields = [];
 
-            if($model->isValidProperty('fields'))
-            {
-                $fields = $model->fields;
-                if(is_string($fields))
-                    $fields = json_decode($model->fields , true);
-            }
-        }
-
-        if(empty($fields) && $this->_object->isValidProperty('fields'))
+        if($this->_object->isValidProperty('fields'))
         {
             $fields = $this->_object->fields;
 
             if(empty($fields))
-                $fields = array();
+                $fields = [];
 
             if(is_string($fields))
                 $fields = json_decode($fields , true);
         }
 
-        $data = array();
+        if($this->_object->isValidProperty('model') && strlen($this->_object->model) && $this->_project->objectExists($this->_object->model))
+        {
+            $model = $this->_project->getObject($this->_object->model);
+
+            if($model->isValidProperty('fields'))
+            {
+                $modelFields = $model->fields;
+
+                if(is_string($modelFields)){
+                    $modelFields = json_decode($modelFields , true);
+                }
+
+                if(!empty($modelFields)){
+                    $fields = array_merge($fields,$modelFields);
+                }
+            }
+        }
+
+        $data = [];
         if(!empty($fields))
         {
             foreach ($fields as $item)
diff --git a/dvelum/app/Backend/Designer/Sub/Viewframe.php b/dvelum/app/Backend/Designer/Sub/Viewframe.php
index ad2f1400..d18e4edf 100644
--- a/dvelum/app/Backend/Designer/Sub/Viewframe.php
+++ b/dvelum/app/Backend/Designer/Sub/Viewframe.php
@@ -97,7 +97,7 @@ public function indexAction()
 			foreach ($includes as $file)
 			{
 	            if(File::getExt($file) == '.css')
-			       $res->addCss($file , false);
+			       $res->addCss($file , 100);
 			    else
 				   $res->addJs($file , false, false);
 			}
diff --git a/dvelum/app/Backend/Orm/Controller.php b/dvelum/app/Backend/Orm/Controller.php
index 2370fee0..2cefe3b8 100644
--- a/dvelum/app/Backend/Orm/Controller.php
+++ b/dvelum/app/Backend/Orm/Controller.php
@@ -560,7 +560,7 @@ protected function _createObject($name , array $data)
             Response::jsonError($this->_lang->FILL_FORM, array(array('id' => 'name', 'msg' => $this->_lang->SB_UNIQUE)));
         }
 
-        if(!is_dir($configDir) && !@mkdir($configDir, 0655, true)){
+        if(!is_dir($configDir) && !@mkdir($configDir, 0640, true)){
             Response::jsonError($this->_lang->CANT_WRITE_FS.' '.$configDir);
         }
 
diff --git a/dvelum/app/Db/Manager.php b/dvelum/app/Db/Manager.php
index e5b0c7b9..2e5442d6 100644
--- a/dvelum/app/Db/Manager.php
+++ b/dvelum/app/Db/Manager.php
@@ -25,7 +25,9 @@ public function __construct(Config_Abstract $appConfig)
      */
     public function getDbConnection($name)
     {
-        $workMode = $this->_appConfig->get('development');       
+        $workMode = $this->_appConfig->get('development');
+        $debug = $this->_appConfig->get('debug_panel');
+
         if(!isset($this->_dbConnections[$workMode][$name]))
         {
            $cfg = $this->getDbConfig($name);
@@ -34,7 +36,7 @@ public function getDbConnection($name)
             * Enable Db profiler for development mode Attention! Db Profiler causes
             * memory leaks at background tasks. (Dev mode)
             */
-            if($this->_appConfig->get('development')){
+            if($this->_appConfig->get('development') && $debug['enabled'] && $debug['options']['sql']){
                 $db->getProfiler()->setEnabled(true);
                 Debug::addDbProfiler($db->getProfiler());
             }
diff --git a/dvelum/app/Install/Controller.php b/dvelum/app/Install/Controller.php
index 5589d724..4f718b5a 100644
--- a/dvelum/app/Install/Controller.php
+++ b/dvelum/app/Install/Controller.php
@@ -451,7 +451,7 @@ public function setuserpassAction()
         $mainCfg = Config::storage()->get('main.php' , false , false);
         $writePath = $mainCfg->getWritePath();
 
-        if(!is_dir(dirname($writePath)) && !@mkdir($writePath , 0655, true)){
+        if(!is_dir(dirname($writePath)) && !@mkdir($writePath , 0755, true)){
             Response::jsonError($this->localization->get('CANT_WRITE_FS').' '.dirname($writePath));
         }
 
diff --git a/dvelum/app/Model/Medialib.php b/dvelum/app/Model/Medialib.php
index 8f381180..f40eb693 100755
--- a/dvelum/app/Model/Medialib.php
+++ b/dvelum/app/Model/Medialib.php
@@ -26,13 +26,14 @@ public function getIdByPath($path)
      * @param integer $size (bytes)
      * @param string $type
      * @param string $ext  - extension
+     * @param string $hash - file hash, optional default null
      * @return integer
      */
-    public function addItem($name , $path , $size , $type, $ext , $category = null)
+    public function addItem($name, $path, $size, $type, $ext, $category = null, $hash=null)
     {
         $size = number_format(($size/1024/1024) , 3);
 
-        $data = array(
+        $data = [
             'title'=>$name,
             'path'=>$path,
             'size'=>$size,
@@ -40,11 +41,13 @@ public function addItem($name , $path , $size , $type, $ext , $category = null)
             'user_id'=>User::getInstance()->id,
             'ext'=>$ext,
             'date'=>date('Y-m-d H:i:s'),
-            'category'=>$category
-        );
+            'category'=>$category,
+            'hash'=> $hash
+        ];
 
         $obj = new Db_Object($this->_name);
         $obj->setValues($data);
+
         if($obj->save()){
             return $obj->getId();
         } else{
@@ -55,8 +58,9 @@ public function addItem($name , $path , $size , $type, $ext , $category = null)
     /**
      * Delete item from library
      * @param integer $id
+     * @return boolean
      */
-    public function remove($id , $log=true)
+    public function remove($id)
     {
         if(!$id)
             return false;
@@ -275,10 +279,6 @@ public function cropAndResize($srcData , $x,$y,$w,$h , $type)
         $conf = $this->getConfig()->__toArray();
         $thumbSizes = $conf['image']['sizes'];
 
-        // sub dir fix
-        if($srcData['path'][0]!=='/')
-            $srcData['path'] = '/'.$srcData['path'];
-
         $path = $docRoot.$srcData['path'];
 
         if(!file_exists($path))
@@ -286,7 +286,11 @@ public function cropAndResize($srcData , $x,$y,$w,$h , $type)
 
         $tmpPath = $appConfig['tmp'].basename($path);
 
-        Image_Resize::cropImage($path, $tmpPath , $x, $y, $w, $h);
+        $path = str_replace('//','/', $path);
+
+        if(!Image_Resize::cropImage($path, $tmpPath , $x, $y, $w, $h)){
+            return false;
+        }
 
         if(!isset($thumbSizes[$type]))
             return false;
@@ -362,4 +366,50 @@ public function updateItemsCategory(array $items , $catalog)
             return false;
         }
     }
+
+    /**
+     * Get file icon
+     * @param $filename
+     * @return string
+     */
+    static public function getFilePic($filename)
+    {
+        $ext = File::getExt($filename);
+        $icon = 'i/system/file.png';
+        switch($ext){
+            case '.jpg':
+            case '.jpeg':
+            case '.gif':
+            case '.bmp':
+            case '.png':
+                $icon = 'i/system/folder-image.png';
+                break;
+            case  '.doc':
+            case  '.docx':
+            case  '.odt':
+            case  '.txt':
+                $icon = 'i/system/doc.png';
+                break;
+
+            case  '.xls':
+            case  '.xlsx':
+            case  '.ods':
+            case  '.csv':
+                $icon = 'i/system/excel.png';
+                break;
+            case '.pdf':
+                $icon = 'i/system/pdf.png';
+                break;
+
+            case '.zip':
+            case '.rar':
+            case '.7z':
+                $icon = 'i/system/archive.png';
+                break;
+
+
+            default :  $icon = 'i/system/file.png';
+        }
+        return $icon;
+    }
 }
\ No newline at end of file
diff --git a/dvelum/app/Model/Permissions.php b/dvelum/app/Model/Permissions.php
index fe34af04..151247a7 100644
--- a/dvelum/app/Model/Permissions.php
+++ b/dvelum/app/Model/Permissions.php
@@ -47,13 +47,17 @@ public function getPermissions($userId , $groupId)
          if(!empty($userRights)){
              foreach ($userRights as $k=>$v){
                  foreach (self::$_fields as $field){
-                     if(isset($v[$field]) && $v[$field]){
-                         $data[$v['module']][$field] = true;
+                     if(isset($v[$field])) {
+                         if($v[$field]){
+                             $data[$v['module']][$field] = true;
+                         }elseif(!isset($data[$v['module']][$field])){
+                             $data[$v['module']][$field] = false;
+                         }
                      }
+
                  }
              }
          }
-         $data = array_merge($data , Utils::rekey('module', $userRights));
          return $data;
     }
 
diff --git a/dvelum/app/Modules/Generator.php b/dvelum/app/Modules/Generator.php
index 41766b78..91ba27b7 100644
--- a/dvelum/app/Modules/Generator.php
+++ b/dvelum/app/Modules/Generator.php
@@ -32,7 +32,7 @@ protected function _createControllerFile($dir , $content)
           if(!is_dir($dir))
               throw new Exception('Invalid controller dir');
       }else{
-          if(!@mkdir($dir , 0777 , true))
+          if(!@mkdir($dir , 0775 , true))
               throw new Exception(Lang::lang()->get('CANT_WRITE_FS') . ' ' . $dir);
       }
 
diff --git a/dvelum/app/Page.php b/dvelum/app/Page.php
index 6d223acc..1852bb43 100644
--- a/dvelum/app/Page.php
+++ b/dvelum/app/Page.php
@@ -119,4 +119,13 @@ public function getThemePath()
     {
         return $this->_templatesPath . $this->theme . '/';
     }
+
+    /**
+     * Set template theme
+     * @param $theme
+     */
+    public function setTheme($theme)
+    {
+        $this->theme = $theme;
+    }
 }
\ No newline at end of file
diff --git a/dvelum/app/Task/Recrop.php b/dvelum/app/Task/Recrop.php
index 58eae799..538273dd 100644
--- a/dvelum/app/Task/Recrop.php
+++ b/dvelum/app/Task/Recrop.php
@@ -68,12 +68,19 @@ public function run()
 	                continue;
 	                       		
 	            $saveName = str_replace($v['ext'], '-'.$typename.$v['ext'], $path);
-	                           
-	            if($conf['image']['thumb_types'][$typename] == 'crop'){
-	                 Image_Resize::resize($path, $thumbSizes[$typename][0], $thumbSizes[$typename][1],$saveName, true,true);
-	            }else{ 
-	                 Image_Resize::resize($path, $thumbSizes[$typename][0], $thumbSizes[$typename][1],$saveName, true,false);
-	            }       
+
+
+                switch($conf['image']['thumb_types'][$typename]){
+                    case 'crop' :
+                        Image_Resize::resize($path, $thumbSizes[$typename][0], $thumbSizes[$typename][1], $saveName, true,true);
+                        break;
+                    case 'resize_fit':
+                        Image_Resize::resize($path, $thumbSizes[$typename][0], $thumbSizes[$typename][1], $saveName, true, false);
+                        break;
+                    case 'resize':
+                        Image_Resize::resize($path, $thumbSizes[$typename][0], $thumbSizes[$typename][1], $saveName, false ,false);
+                        break;
+                }
             }                  
             /*
              * Update task status and check for signals 
diff --git a/dvelum/app/Trigger.php b/dvelum/app/Trigger.php
index 0e3b2133..2ee331d7 100644
--- a/dvelum/app/Trigger.php
+++ b/dvelum/app/Trigger.php
@@ -170,7 +170,7 @@ public function onAfterPublish(Db_Object $object)
         }
     }
 
-    public function  onAfterUnpublish(Db_Object $object)
+    public function onAfterUnpublish(Db_Object $object)
     {
         if(!$object->getConfig()->hasHistory()) {
             return;
@@ -204,4 +204,8 @@ public function onAfterAddVersion(Db_Object $object)
         );
 
     }
+
+    public function onAfterInsertBeforeCommit(Db_Object $object){}
+
+    public function onAfterDeleteBeforeCommit(Db_Object $object){}
 }
\ No newline at end of file
diff --git a/dvelum/library/Bgtask/Storage/Orm.php b/dvelum/library/Bgtask/Storage/Orm.php
index f643acf7..b1e532d8 100644
--- a/dvelum/library/Bgtask/Storage/Orm.php
+++ b/dvelum/library/Bgtask/Storage/Orm.php
@@ -84,7 +84,7 @@ public function signal($pid , $signal)
      */
      public function kill($pid)
      {
-     	$this->_objectModel->remove($pid , false);
+     	$this->_objectModel->remove($pid);
      	$this->_signalModel->clearSignals($pid);
      		
      	if(isset($this->_objects[$pid]))
diff --git a/dvelum/library/Db/Object/Builder.php b/dvelum/library/Db/Object/Builder.php
index 48b82987..e464916b 100644
--- a/dvelum/library/Db/Object/Builder.php
+++ b/dvelum/library/Db/Object/Builder.php
@@ -1279,7 +1279,7 @@ protected function updateRelations($list)
             if(file_exists($configDir . strtolower($newObjectName).'.php'))
                 throw new Exception($lang->get('INVALID_VALUE').' Object Name: '.$newObjectName .' '.$lang->get('SB_UNIQUE'));
 
-            if(!is_dir($configDir) && !@mkdir($configDir, 0655, true)){
+            if(!is_dir($configDir) && !@mkdir($configDir, 0755, true)){
                 Response::jsonError($lang->get('CANT_WRITE_FS').' '.$configDir);
             }
 
diff --git a/dvelum/library/Db/Object/Event/Manager.php b/dvelum/library/Db/Object/Event/Manager.php
index 154ea928..979f4d7c 100644
--- a/dvelum/library/Db/Object/Event/Manager.php
+++ b/dvelum/library/Db/Object/Event/Manager.php
@@ -20,6 +20,9 @@ abstract class Db_Object_Event_Manager{
 	const AFTER_UNPUBLISH = 'onAfterUnpublish';
 	const AFTER_PUBLISH = 'onAfterPublish';
 	const AFTER_UPDATE_BEFORE_COMMIT = 'onAfterUpdateBeforeCommit';
+	const AFTER_INSERT_BEFORE_COMMIT = 'onAfterInsertBeforeCommit';
+	const AFTER_DELETE_BEFORE_COMMIT = 'onAfterDeleteBeforeCommit';
+
 	/**
 	 * Find and run event triggers
 	 * Note that onBeforeDelete and onAfterDelete events provide "SpacialCase" empty Db_Object
diff --git a/dvelum/library/Db/Object/Store.php b/dvelum/library/Db/Object/Store.php
index df3b5c1f..a6a315fa 100755
--- a/dvelum/library/Db/Object/Store.php
+++ b/dvelum/library/Db/Object/Store.php
@@ -30,10 +30,10 @@ class Db_Object_Store
 
     public function __construct(array $config = array())
     {
-       if(empty($options))
-           return;
+        if(empty($options))
+            return;
 
-       $this->config =  array_merge($this->config , $config);
+        $this->config =  array_merge($this->config , $config);
     }
     /**
      * Get links object name
@@ -41,7 +41,7 @@ public function __construct(array $config = array())
      */
     public function getLinksObjectName()
     {
-    	return $this->config['linksObject'];
+        return $this->config['linksObject'];
     }
     /**
      * Get history object name
@@ -49,7 +49,7 @@ public function getLinksObjectName()
      */
     public function getHistoryObjectName()
     {
-    	return $this->config['historyObject'];
+        return $this->config['historyObject'];
     }
     /**
      * Get version object name
@@ -57,7 +57,7 @@ public function getHistoryObjectName()
      */
     public function getVersionObjectName()
     {
-    	return $this->config['versionObject'];
+        return $this->config['versionObject'];
     }
     /**
      * Set log Adapter
@@ -65,7 +65,7 @@ public function getVersionObjectName()
      */
     public function setLog(Log $log)
     {
-    	$this->_log = $log;
+        $this->_log = $log;
     }
     /**
      * Set event manager
@@ -73,12 +73,12 @@ public function setLog(Log $log)
      */
     public function setEventManager(Db_Object_Event_Manager $obj)
     {
-    	$this->_eventManager = $obj;
+        $this->_eventManager = $obj;
     }
 
     protected function _getDbConnection(Db_Object $object)
     {
-    	return Model::factory($object->getName())->getDbConnection();
+        return Model::factory($object->getName())->getDbConnection();
     }
     /**
      * Update Db object
@@ -96,10 +96,10 @@ public function update(Db_Object $object , $transaction = true)
             return false;
         }
 
-    	 /*
-    	  * Check object id
-    	  */
-    	  if(!$object->getId())
+        /*
+         * Check object id
+         */
+        if(!$object->getId())
             return false;
 
         /*
@@ -114,59 +114,59 @@ public function update(Db_Object $object , $transaction = true)
         if($this->_eventManager)
             $this->_eventManager->fireEvent(Db_Object_Event_Manager::BEFORE_UPDATE, $object);
 
-       /*
-        * Validate unique values
-        *
-        $values = $object->validateUniqueValues();
-
-        if(!empty($values))
-        {
-          if($this->_log)
-          {
-            $errors = array();
-            foreach($values as $k => $v)
-            {
-              $errors[] = $k . ':' . $v;
-            }
-            $this->_log->log($object->getName() . '::update ' . implode(', ' , $errors));
-          }
-          return false;
-        }
-        */
+        /*
+         * Validate unique values
+         *
+         $values = $object->validateUniqueValues();
+
+         if(!empty($values))
+         {
+           if($this->_log)
+           {
+             $errors = array();
+             foreach($values as $k => $v)
+             {
+               $errors[] = $k . ':' . $v;
+             }
+             $this->_log->log($object->getName() . '::update ' . implode(', ' , $errors));
+           }
+           return false;
+         }
+         */
 
-	      /*
-	       * Check if DB table support transactions
-	       */
-         $transact = $object->getConfig()->isTransact();
-         /*
-          * Get Database connector for object model;
-          */
-         $db = $this->_getDbConnection($object);
+        /*
+         * Check if DB table support transactions
+         */
+        $transact = $object->getConfig()->isTransact();
+        /*
+         * Get Database connector for object model;
+         */
+        $db = $this->_getDbConnection($object);
 
-	     if($transact && $transaction)
-	    	 $db->beginTransaction();
+        if($transact && $transaction)
+            $db->beginTransaction();
 
         $success = $this->_updateOperation($object);
 
         if(!$success)
-	     {
-	     	if($transact && $transaction)
-	        	$db->rollBack();
-	        return false;
-	     }
-	     else
-	     {
-	     	if($transact && $transaction)
-        		$db->commit();
-	     }
-
-         /*
-          * Fire "AFTER_UPDATE" Event if event manager exists
-          */
-         if($this->_eventManager)
+        {
+            if($transact && $transaction)
+                $db->rollBack();
+            return false;
+        }
+        else
+        {
+            if($transact && $transaction)
+                $db->commit();
+        }
+
+        /*
+         * Fire "AFTER_UPDATE" Event if event manager exists
+         */
+        if($this->_eventManager)
             $this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_UPDATE, $object);
 
-	     return $object->getId();
+        return $object->getId();
     }
 
     protected function _updateOperation(Db_Object $object)
@@ -181,7 +181,7 @@ protected function _updateOperation(Db_Object $object)
             $this->_updateLinks($object);
 
             $updates = $object->serializeLinks($updates);
-            
+
             if(!empty($updates))
                 $db->update($object->getTable() , $updates, $db->quoteIdentifier($object->getConfig()->getPrimaryKey()).' = '.$object->getId());
 
@@ -190,6 +190,7 @@ protected function _updateOperation(Db_Object $object)
              */
             if($this->_eventManager)
                 $this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_UPDATE_BEFORE_COMMIT, $object);
+
             $object->commitChanges();
 
             return true;
@@ -211,135 +212,135 @@ protected function _updateOperation(Db_Object $object)
      */
     public function unpublish(Db_Object $object , $transaction = true)
     {
-    	if($object->getConfig()->isReadOnly())
-    	{
-    		if($this->_log)
-    			$this->_log->log('ORM :: cannot unpublish readonly object '. $object->getConfig()->getName());
-
-    		return false;
-    	}
-
-       /*
-    	* Check object id
-    	*/
-    	if(!$object->getId())
-    		return false;
-
-    	if (!$object->getConfig()->isRevControl())
-    	{
-    		if($this->_log){
-    			$this->_log->log($object->getName().'::unpublish Cannot unpublish object is not under version control');
-    		}
-    		return false;
-    	}
-
-       /*
-        * Fire "BEFORE_UNPUBLISH" Event if event manager exists
-    	*/
-    	if($this->_eventManager)
-    		$this->_eventManager->fireEvent(Db_Object_Event_Manager::BEFORE_UNPUBLISH, $object);
-
-       /*
-    	* Check if DB table support transactions
-    	*/
-    	$transact = $object->getConfig()->isTransact();
-    	/*
-    	 * Get Database connector for object model;
-    	*/
-    	$db = $this->_getDbConnection($object);
-
-    	if($transact && $transaction)
-    		$db->beginTransaction();
-
-    	$success = $this->_updateOperation($object);
-
-    	if(!$success)
-    	{
-    		if($transact && $transaction)
-    			$db->rollBack();
-    		return false;
-    	}
-    	else
-    	{
-    		if($transact && $transaction)
-    			$db->commit();
-    	}
-    	/*
-    	 * Fire "AFTER_UPDATE" Event if event manager exists
-    	*/
-    	if($this->_eventManager)
-    		$this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_UNPUBLISH, $object);
-
-    	return true;
+        if($object->getConfig()->isReadOnly())
+        {
+            if($this->_log)
+                $this->_log->log('ORM :: cannot unpublish readonly object '. $object->getConfig()->getName());
+
+            return false;
+        }
+
+        /*
+         * Check object id
+         */
+        if(!$object->getId())
+            return false;
+
+        if (!$object->getConfig()->isRevControl())
+        {
+            if($this->_log){
+                $this->_log->log($object->getName().'::unpublish Cannot unpublish object is not under version control');
+            }
+            return false;
+        }
+
+        /*
+         * Fire "BEFORE_UNPUBLISH" Event if event manager exists
+         */
+        if($this->_eventManager)
+            $this->_eventManager->fireEvent(Db_Object_Event_Manager::BEFORE_UNPUBLISH, $object);
+
+        /*
+         * Check if DB table support transactions
+         */
+        $transact = $object->getConfig()->isTransact();
+        /*
+         * Get Database connector for object model;
+        */
+        $db = $this->_getDbConnection($object);
+
+        if($transact && $transaction)
+            $db->beginTransaction();
+
+        $success = $this->_updateOperation($object);
+
+        if(!$success)
+        {
+            if($transact && $transaction)
+                $db->rollBack();
+            return false;
+        }
+        else
+        {
+            if($transact && $transaction)
+                $db->commit();
+        }
+        /*
+         * Fire "AFTER_UPDATE" Event if event manager exists
+        */
+        if($this->_eventManager)
+            $this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_UNPUBLISH, $object);
+
+        return true;
     }
 
-   /**
-    * Publish Db_Object
-    * @param Db_Object $object
-    * @param boolean $transaction - optional, default true
-    * @return boolean
-    */
+    /**
+     * Publish Db_Object
+     * @param Db_Object $object
+     * @param boolean $transaction - optional, default true
+     * @return boolean
+     */
     public function publish(Db_Object $object, $transaction = true)
     {
-    	if($object->getConfig()->isReadOnly())
-    	{
-    		if($this->_log)
-    			$this->_log->log('ORM :: cannot publish readonly object '. $object->getConfig()->getName());
-
-    		return false;
-    	}
-       /*
-    	* Check object id
-    	*/
-    	if(!$object->getId())
-    		return false;
-
-    	if(!$object->getConfig()->isRevControl())
-    	{
-    		if($this->_log){
-    			$this->_log->log($object->getName().'::publish Cannot publish object is not under version control');
-    		}
-    		return false;
-    	}
-
-    	/*
-    	 * Fire "BEFORE_UNPUBLISH" Event if event manager exists
-    	*/
-    	if($this->_eventManager)
-    		$this->_eventManager->fireEvent(Db_Object_Event_Manager::BEFORE_PUBLISH, $object);
-
-    	/*
-    	 * Check if DB table support transactions
-    	*/
-    	$transact = $object->getConfig()->isTransact();
-    	/*
-    	 * Get Database connector for object model;
-    	*/
-    	$db = $this->_getDbConnection($object);
-
-    	if($transact && $transaction)
-    		$db->beginTransaction();
-
-    	$success = $this->_updateOperation($object);
-
-    	if(!$success)
-    	{
-    		if($transact && $transaction)
-    			$db->rollBack();
-    		return false;
-    	}
-    	else
-    	{
-    		if($transact && $transaction)
-    			$db->commit();
-    	}
-    	/*
-    	 * Fire "AFTER_UPDATE" Event if event manager exists
-    	 */
-    	if($this->_eventManager)
-    		$this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_PUBLISH, $object);
-
-    	return true;
+        if($object->getConfig()->isReadOnly())
+        {
+            if($this->_log)
+                $this->_log->log('ORM :: cannot publish readonly object '. $object->getConfig()->getName());
+
+            return false;
+        }
+        /*
+         * Check object id
+         */
+        if(!$object->getId())
+            return false;
+
+        if(!$object->getConfig()->isRevControl())
+        {
+            if($this->_log){
+                $this->_log->log($object->getName().'::publish Cannot publish object is not under version control');
+            }
+            return false;
+        }
+
+        /*
+         * Fire "BEFORE_UNPUBLISH" Event if event manager exists
+        */
+        if($this->_eventManager)
+            $this->_eventManager->fireEvent(Db_Object_Event_Manager::BEFORE_PUBLISH, $object);
+
+        /*
+         * Check if DB table support transactions
+        */
+        $transact = $object->getConfig()->isTransact();
+        /*
+         * Get Database connector for object model;
+        */
+        $db = $this->_getDbConnection($object);
+
+        if($transact && $transaction)
+            $db->beginTransaction();
+
+        $success = $this->_updateOperation($object);
+
+        if(!$success)
+        {
+            if($transact && $transaction)
+                $db->rollBack();
+            return false;
+        }
+        else
+        {
+            if($transact && $transaction)
+                $db->commit();
+        }
+        /*
+         * Fire "AFTER_UPDATE" Event if event manager exists
+         */
+        if($this->_eventManager)
+            $this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_PUBLISH, $object);
+
+        return true;
     }
 
     protected function _updateLinks(Db_Object $object)
@@ -347,11 +348,11 @@ protected function _updateLinks(Db_Object $object)
         $updates = $object->getUpdates();
 
         if(empty($updates))
-        	return true;
+            return true;
 
         foreach ($updates as $k=>$v)
         {
-        	$conf = $object->getConfig()->getFieldConfig($k);
+            $conf = $object->getConfig()->getFieldConfig($k);
 
             if($object->getConfig()->isMultiLink($k))
             {
@@ -401,8 +402,8 @@ protected function _clearLinks(Db_Object $object ,$objectField , $targetObjectNa
             $db->delete($linksObjModel->table() , $where);
             return true;
         } catch (Exception $e){
-        	if($this->_log)
-        		$this->_log->log($object->getName().'::_clearLinks '.$e->getMessage());
+            if($this->_log)
+                $this->_log->log($object->getName().'::_clearLinks '.$e->getMessage());
             return false;
         }
     }
@@ -470,34 +471,34 @@ public function insert(Db_Object $object , $transaction = true)
             return false;
         }
 
-    	if($this->_eventManager)
+        if($this->_eventManager)
             $this->_eventManager->fireEvent(Db_Object_Event_Manager::BEFORE_ADD, $object);
-       /*
-	    * Check if DB table support transactions
-	    */
-    	$transact = $object->getConfig()->isTransact();
+        /*
+         * Check if DB table support transactions
+         */
+        $transact = $object->getConfig()->isTransact();
 
-    	$db = $this->_getDbConnection($object);
+        $db = $this->_getDbConnection($object);
 
-    	if($transact && $transaction)
-    		$db->beginTransaction();
+        if($transact && $transaction)
+            $db->beginTransaction();
 
-    	$success = $this->_insertOperation($object);
+        $success = $this->_insertOperation($object);
 
         if(!$success)
         {
-        	if($transact && $transaction)
-        		$db->rollBack();
-        	return false;
+            if($transact && $transaction)
+                $db->rollBack();
+            return false;
         }
         else
         {
-        	if($transact && $transaction)
-        		$db->commit();
+            if($transact && $transaction)
+                $db->commit();
         }
 
         if($this->_eventManager)
-        	$this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_ADD, $object);
+            $this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_ADD, $object);
 
         return $object->getId();
     }
@@ -535,14 +536,14 @@ public function encryptData(Db_Object $object , $data)
 
     protected function _insertOperation(Db_Object $object)
     {
-    	$insertId = $object->getInsertId();
+        $insertId = $object->getInsertId();
 
-    	if($insertId){
-    		$updates = array_merge($object->getData() , $object->getUpdates());
-    		$updates[$object->getConfig()->getPrimaryKey()] = $insertId;
-    	}else{
-    		$updates =  $object->getUpdates();
-    	}
+        if($insertId){
+            $updates = array_merge($object->getData() , $object->getUpdates());
+            $updates[$object->getConfig()->getPrimaryKey()] = $insertId;
+        }else{
+            $updates =  $object->getUpdates();
+        }
 
         if($object->getConfig()->hasEncrypted())
             $updates = $this->encryptData($object , $updates);
@@ -572,81 +573,102 @@ protected function _insertOperation(Db_Object $object)
 
         $objectTable = $object->getTable();
 
-    	if(!$db->insert($objectTable, $object->serializeLinks($updates)))
-             return false;
+        try{
+            $db->insert($objectTable, $object->serializeLinks($updates));
+        }catch (Exception $e){
+            if($this->_log){
+                $this->_log->log($object->getName().'::_insertOperation '.$e->getMessage());
+            }
 
+            return false;
+        }
         $id = $db->lastInsertId($objectTable , $object->getConfig()->getPrimaryKey());
 
         if(!$id)
-           return false;
+            return false;
 
         $object->setId($id);
 
         if(!$this->_updateLinks($object))
-           return false;
+            return false;
+
+        try{
+            /*
+             * Fire "AFTER_UPDATE_BEFORE_COMMIT" Event if event manager exists
+             */
+            if($this->_eventManager){
+                $this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_INSERT_BEFORE_COMMIT, $object);
+            }
+        }catch (Exception $e){
+
+            if($this->_log)
+                $this->_log->log($object->getName().'::_insertOperation '.$e->getMessage());
+
+            return false;
+        }
 
         $object->commitChanges();
         $object->setId($id);
 
-	    return true;
+        return true;
     }
 
-	/**
-	 * Add new object version
-	 * @param Db_Object $object
+    /**
+     * Add new object version
+     * @param Db_Object $object
      * @param boolean $log - optional, log changes
      * @param boolean $useTransaction - optional , use transaction if available
-	 * @return boolean|integer - vers number
-	 */
+     * @return boolean|integer - vers number
+     */
     public function addVersion(Db_Object $object , $log = true , $useTransaction = true)
     {
 
-    	if($object->getConfig()->isReadOnly())
-    	{
-    		if($this->_log)
-    			$this->_log->log('ORM :: cannot addVersion for readonly object '. $object->getConfig()->getName());
-
-    		return false;
-    	}
-    	/*
-    	 * Check object id
-    	*/
-    	if(!$object->getId())
-    		return false;
-
-    	if(!$object->getConfig()->isRevControl())
-    	{
-    		if($this->_log)
-    			$this->_log->log($object->getName().'::publish Cannot addVersion. Object is not under version control');
-
-    		return false;
-    	}
-
-    	/*
-    	 * Fire "BEFORE_ADD_VERSION" Event if event manager exists
-    	*/
-    	if($this->_eventManager)
-    		$this->_eventManager->fireEvent(Db_Object_Event_Manager::BEFORE_ADD_VERSION, $object);
-
-       /*
-    	* Create new revision
-    	*/
-    	$versNum = Model::factory($this->config['versionObject'])->newVersion($object);
-
-    	if(!$versNum)
-    		return false;
-
-    	try{
+        if($object->getConfig()->isReadOnly())
+        {
+            if($this->_log)
+                $this->_log->log('ORM :: cannot addVersion for readonly object '. $object->getConfig()->getName());
+
+            return false;
+        }
+        /*
+         * Check object id
+        */
+        if(!$object->getId())
+            return false;
+
+        if(!$object->getConfig()->isRevControl())
+        {
+            if($this->_log)
+                $this->_log->log($object->getName().'::publish Cannot addVersion. Object is not under version control');
+
+            return false;
+        }
+
+        /*
+         * Fire "BEFORE_ADD_VERSION" Event if event manager exists
+        */
+        if($this->_eventManager)
+            $this->_eventManager->fireEvent(Db_Object_Event_Manager::BEFORE_ADD_VERSION, $object);
+
+        /*
+         * Create new revision
+         */
+        $versNum = Model::factory($this->config['versionObject'])->newVersion($object);
+
+        if(!$versNum)
+            return false;
+
+        try{
             $oldObject = new Db_Object($object->getName() , $object->getId());
             /**
-    		 * Update object if not published
-    		 */
+             * Update object if not published
+             */
             if(!$oldObject->get('published')){
                 $data = $object->getData();
 
-    			foreach($data as $k => $v)
-    				if(!is_null($v))
-    					$oldObject->set($k , $v);
+                foreach($data as $k => $v)
+                    if(!is_null($v))
+                        $oldObject->set($k , $v);
 
             }
 
@@ -660,16 +682,16 @@ public function addVersion(Db_Object $object , $log = true , $useTransaction = t
         }catch(Exception $e){
             if($this->_log)
                 $this->_log->log('Cannot update unpublished object data '. $e->getMessage());
-    		return false;
-    	}
+            return false;
+        }
 
-    	/*
-    	 * Fire "AFTER_ADD_VERSION" Event if event manager exists
-    	 */
-    	if($this->_eventManager)
-    		$this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_ADD_VERSION, $object);
+        /*
+         * Fire "AFTER_ADD_VERSION" Event if event manager exists
+         */
+        if($this->_eventManager)
+            $this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_ADD_VERSION, $object);
 
-    	return  $versNum;
+        return  $versNum;
     }
 
     /**
@@ -680,8 +702,9 @@ public function addVersion(Db_Object $object , $log = true , $useTransaction = t
      */
     public function delete(Db_Object $object , $transaction = true)
     {
+        $objectConfig = $object->getConfig();
 
-        if($object->getConfig()->isReadOnly())
+        if($objectConfig->isReadOnly())
         {
             if($this->_log)
                 $this->_log->log('ORM :: cannot delete readonly object '. $object->getName());
@@ -693,21 +716,46 @@ public function delete(Db_Object $object , $transaction = true)
             return false;
 
         if($this->_eventManager)
-        	$this->_eventManager->fireEvent(Db_Object_Event_Manager::BEFORE_DELETE, $object);
+            $this->_eventManager->fireEvent(Db_Object_Event_Manager::BEFORE_DELETE, $object);
 
         $transact = $object->getConfig()->isTransact();
 
         $db = $this->_getDbConnection($object);
 
-    	if($transact && $transaction)
-    		$db->beginTransaction();
+        if($transact && $transaction)
+            $db->beginTransaction();
 
-        Model::factory($this->config['linksObject'])->clearObjectLinks($object);
+        $fields = $objectConfig->getFieldsConfig();
 
-        if($db->delete($object->getTable(), $db->quoteIdentifier($object->getConfig()->getPrimaryKey()).' =' . $object->getId()))
-        {
-        	$success= true;
-        } else{
+        foreach ($fields as $field=>$conf) {
+            if($objectConfig->isMultiLink($field)){
+                if(!$this->_clearLinks($object, $field, $objectConfig->getLinkedObject($field))){
+                    return false;
+                }
+            }
+        }
+
+        try{
+            $db->delete($object->getTable(), $db->quoteIdentifier($object->getConfig()->getPrimaryKey()).' =' . $object->getId());
+            $success = true;
+        }catch (Exception $e){
+            if($this->_log){
+                $this->_log->log($object->getName().'::delete '.$e->getMessage());
+            }
+            $success = false;
+        }
+
+        try{
+            /*
+             * Fire "AFTER_UPDATE_BEFORE_COMMIT" Event if event manager exists
+             */
+            if($this->_eventManager){
+                $this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_DELETE_BEFORE_COMMIT, $object);
+            }
+        }catch (Exception $e){
+            if($this->_log){
+                $this->_log->log($object->getName().'::delete '.$e->getMessage());
+            }
             $success = false;
         }
 
@@ -719,8 +767,9 @@ public function delete(Db_Object $object , $transaction = true)
                 $db->rollBack();
         }
 
-        if($this->_eventManager)
-        	$this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_DELETE, $object);
+        if($success && $this->_eventManager){
+            $this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_DELETE, $object);
+        }
 
         return $success;
     }
@@ -745,31 +794,31 @@ public function deleteObjects($objectName, array $ids)
         $objectModel = Model::factory($objectName);
         $tableName = $objectModel->table();
 
-    	if(empty($ids))
-    		return true;
+        if(empty($ids))
+            return true;
 
-    	$specialCase = Db_Object::factory($objectName);
+        $specialCase = Db_Object::factory($objectName);
 
-    	$db = $this->_getDbConnection($specialCase);
+        $db = $this->_getDbConnection($specialCase);
 
-	    $where = $db->quoteInto('`id` IN(?)', $ids);
+        $where = $db->quoteInto('`id` IN(?)', $ids);
 
-	    if($this->_eventManager)
-	    {
-	       	foreach ($ids as $id)
-	       	{
-	       		$specialCase->setId($id);
-	       		$this->_eventManager->fireEvent(Db_Object_Event_Manager::BEFORE_DELETE, $specialCase);
-	       	}
-	    }
+        if($this->_eventManager)
+        {
+            foreach ($ids as $id)
+            {
+                $specialCase->setId($id);
+                $this->_eventManager->fireEvent(Db_Object_Event_Manager::BEFORE_DELETE, $specialCase);
+            }
+        }
 
-	    if(!$db->delete($tableName, $where))
-	    	return false;
+        if(!$db->delete($tableName, $where))
+            return false;
 
-	    /*
-	     * Clear object liks (links from object)
-	     */
-	    Model::factory($this->config['linksObject'])->clearLinksFor($objectName , $ids);
+        /*
+         * Clear object liks (links from object)
+         */
+        Model::factory($this->config['linksObject'])->clearLinksFor($objectName , $ids);
 
         $history = Model::factory($this->config['historyObject']);
         $userId = User::getInstance()->id;
@@ -778,19 +827,19 @@ public function deleteObjects($objectName, array $ids)
          * Save history if required
          */
         if($objectConfig->hasHistory())
-         	foreach ($ids as $v)
-        		$history->log($userId, $v, Model_Historylog::Delete , $tableName);
+            foreach ($ids as $v)
+                $history->log($userId, $v, Model_Historylog::Delete , $tableName);
 
         if($this->_eventManager)
         {
-        	/*
-        	 * Fire "AFTER_DELETE" event for each deleted object
-        	 */
-	        foreach ($ids as $id)
-	        {
-	        	$specialCase->setId($id);
-	        	$this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_DELETE, $specialCase);
-	        }
+            /*
+             * Fire "AFTER_DELETE" event for each deleted object
+             */
+            foreach ($ids as $id)
+            {
+                $specialCase->setId($id);
+                $this->_eventManager->fireEvent(Db_Object_Event_Manager::AFTER_DELETE, $specialCase);
+            }
         }
         return true;
     }
diff --git a/dvelum/library/Designer/Factory.php b/dvelum/library/Designer/Factory.php
index 3898ab15..f3ee3578 100644
--- a/dvelum/library/Designer/Factory.php
+++ b/dvelum/library/Designer/Factory.php
@@ -134,8 +134,7 @@ static public function runProject($projectFile , Config_Abstract $designerConfig
                     if(strpos($file , '?') === false){
                         $file = $file .'?'. $cachedKey;
                     }
-
-                    $resource->addCss($file , false);
+                    $resource->addCss($file , 100);
                 }else{
 
                     if(strpos($file , '?') === false){
diff --git a/dvelum/library/Designer/Project/Code.php b/dvelum/library/Designer/Project/Code.php
index 55de741d..847a332f 100644
--- a/dvelum/library/Designer/Project/Code.php
+++ b/dvelum/library/Designer/Project/Code.php
@@ -259,10 +259,13 @@ public function getObjectDefineJs($id)
 
         if(!empty($objectEvents))
         {
-            if($object->isInstance())
-                $eventsConfig = $object->getObject()->getConfig()->getEvents()->__toArray();
-            else
-                $eventsConfig = $object->getConfig()->getEvents()->__toArray();
+            $eventObject = $object;
+
+            while (method_exists($eventObject, 'getObject')){
+                $eventObject = $eventObject->getObject();
+            }
+
+            $eventsConfig = $eventObject->getConfig()->getEvents()->__toArray();
 
             foreach ($objectEvents as $event => $config)
             {
@@ -333,7 +336,13 @@ public function getObjectLayoutCode($id)
         $eventManager = $this->_project->getEventManager();
         $objectEvents = $eventManager->getObjectEvents($id);
 
-        $eventsConfig = $object->getConfig()->getEvents()->__toArray();
+        $eventObject = $object;
+
+        while (method_exists($eventObject, 'getObject')){
+            $eventObject = $eventObject->getObject();
+        }
+
+        $eventsConfig = $eventObject->getConfig()->getEvents()->__toArray();
 
         // set handlers
         if(isset($objectEvents['handler'])){
@@ -354,11 +363,13 @@ public function getObjectLayoutCode($id)
                 if(isset($eventsConfig[$event]))
                     $params = implode(',', array_keys($eventsConfig[$event]));
 
-                if($event === 'handler')
+                if($event === 'handler'){
                     continue;
-                //$object->addListener($event ,"function(".$params."){\n".Utils_String::addIndent($config['code'],2)."\n}");
-                else
+                } else{
                     $object->addListener($event ,"{\n\t\t\tfn:function(".$params."){\n".Utils_String::addIndent($config['code'],2)."\n},\n\t\t\tscope:this\n\t\t}\n");
+                }
+
+                //$object->addListener($event ,"function(".$params."){\n".Utils_String::addIndent($config['code'],2)."\n}");
             }
         }
 
@@ -761,7 +772,12 @@ protected function _compileExtendedSubItems($parent , $mainContainer)
 
             if(!empty($objectEvents))
             {
-                $eventsConfig = $item['data']->getConfig()->getEvents()->__toArray();
+                $eventObject = $item['data'];
+
+                while (method_exists($eventObject, 'getObject')){
+                    $eventObject = $eventObject->getObject();
+                }
+                $eventsConfig = $eventObject->getConfig()->getEvents()->__toArray();
 
                 foreach ($objectEvents as $event => $config)
                 {
diff --git a/dvelum/library/Ext/Component/Filter.php b/dvelum/library/Ext/Component/Filter.php
index 15a8ba8c..3351f463 100644
--- a/dvelum/library/Ext/Component/Filter.php
+++ b/dvelum/library/Ext/Component/Filter.php
@@ -11,12 +11,22 @@ protected function _initDefaultProperties()
 	/**
 	 * Get visualisation object
 	 * @return Ext_Object
+     * @deprecated
 	 */
 	public function getViewObject()
 	{
-		return $this->_viewObject;
+		return $this->getObject();
 	}
 
+    /**
+     * Get visualisation object
+     * @return Ext_Object
+     */
+	public function getObject()
+    {
+        return $this->_viewObject;
+    }
+
 	/**
 	 * Set visualisation object
 	 * @param Ext_Object $object
@@ -46,38 +56,45 @@ public function __toString()
 		if($this->_config->isValidProperty('autoFilter') && intval($this->_config->autoFilter))
 			$autoFilter = true;
 
-		$object = $this->getViewObject();
+		$object = $this->getObject();
 
-		if(strlen($store) && strlen($field))
+		if(strlen($store) && strlen($field) && $autoFilter)
 		{
-			$listener = 'function(fld){
-			';
-
-			if($autoFilter)
-			{
-				if($local)
-				{
-					$listener.= $store.'.filter("'.$field.'" , fld.getValue());';
-				}
-				else
-				{
-					if($this->_viewObject->isValidProperty('multiSelect') && $this->_viewObject->multiSelect){
-						$listener.= $store.'.proxy.setExtraParam("filter['.$field.'][]" , fld.getValue());';
-					}else{
-						$listener.= $store.'.proxy.setExtraParam("filter['.$field.']" , fld.getValue());';
-					}
-					$listener.= $store.'.loadPage(1);';
-				}
-			}
-			$listener.='
-			 }';
-
-            if($this->_viewObject->getClass() == 'Form_Field_Combobox') {
-                $object->addListener('select', $listener);
-            } else {
-                $object->addListener('change', $listener);
-            }
+                $listener = 'function(fld){
+                ';
+
+
+                    if($local)
+                    {
+                        $listener.= $store.'.filter("'.$field.'" , fld.getValue());';
+                    }
+                    else
+                    {
+                        if($this->_viewObject->isValidProperty('multiSelect') && $this->_viewObject->multiSelect){
+                            $listener.= $store.'.proxy.setExtraParam("filter['.$field.'][]" , fld.getValue());';
+                        }else{
+                            $listener.= $store.'.proxy.setExtraParam("filter['.$field.']" , fld.getValue());';
+                        }
+                        $listener.= $store.'.loadPage(1);';
+                    }
+
+            $listener.= "\n".'}';
+
+                if($this->_viewObject->getClass() == 'Form_Field_Combobox') {
+                    $object->addListener('select', $listener);
+                } else {
+                    $object->addListener('change', $listener);
+                }
 		}
+
+		// copy listeners
+        $listeners = $this->getListeners();
+        if(!empty($listeners)){
+            foreach ($listeners as $name=>$code){
+                $object->addListener($name,$code);
+            }
+        }
+
 		return $object->__toString();
 	}
 
diff --git a/dvelum/library/Ext/Events/Form/Field/Tag.php b/dvelum/library/Ext/Events/Form/Field/Tag.php
new file mode 100644
index 00000000..e4139391
--- /dev/null
+++ b/dvelum/library/Ext/Events/Form/Field/Tag.php
@@ -0,0 +1,9 @@
+'Ext.form.field.Tag',
+        'height'=>'integer',
+        'eOpts'=>'Object'
+    ];
+}
\ No newline at end of file
diff --git a/dvelum/library/Ext/Model.php b/dvelum/library/Ext/Model.php
index a10b4bb9..8b1abf7c 100644
--- a/dvelum/library/Ext/Model.php
+++ b/dvelum/library/Ext/Model.php
@@ -250,10 +250,21 @@ public function getDefineJs($namespace = false)
 		if($namespace)
 			$name = $namespace.'.'.$this->getName();
 		else 
-			$name = $this->getName();			
+			$name = $this->getName();
+
+        if(!empty($this->_fields) && $this->_config->isValidProperty('fields'))
+        {
+//            foreach ($this->_fields as $field)
+//            {
+//                if($field->getConfig()->isValidProperty('mapping') && strlen($field->mapping))
+//                {
+//                    $model = Ext_Code::appendNamespace($field->mapping);
+//                    $field->mapping = $model;
+//                }
+//            }
+            $this->fields = '['.implode(',',array_values($this->_fields)).']';
+        }
 
-		 if(!empty($this->_fields) && $this->_config->isValidProperty('fields'))
-	        $this->fields = '['.implode(',',array_values($this->_fields)).']';
 			
 		$code = "\n".'Ext.define("'.$name.'",{'."\n".
 			"\t".'extend:"'.$this->_config->getExtends().'",'."\n".
@@ -267,9 +278,20 @@ public function getDefineJs($namespace = false)
 	 */
 	public function __toString()
 	{
+
 	    if(!empty($this->_fields) && $this->_config->isValidProperty('fields'))
-	        $this->fields = '['.implode(',',array_values($this->_fields)).']';
-	    
+	    {
+            foreach ($this->_fields as $field)
+            {
+                if($field->getConfig()->isValidProperty('mapping') && strlen($field->mapping))
+                {
+                    $model = Ext_Code::appendNamespace($field->mapping);
+                    $field->mapping = $model;
+                }
+            }
+
+            $this->fields = '['.implode(',',array_values($this->_fields)).']';
+        }
 		return parent::__toString();
 	}
 	/**
diff --git a/dvelum/library/Ext/Object.php b/dvelum/library/Ext/Object.php
index 3cd4f973..5e00f3ea 100644
--- a/dvelum/library/Ext/Object.php
+++ b/dvelum/library/Ext/Object.php
@@ -124,6 +124,15 @@ public function addListener($name , $value)
 		$this->_listeners[$name] = $value;
 	}
 
+    /**
+     * Get event handlers
+     * @return array
+     */
+	public function getListeners()
+    {
+        return $this->_listeners;
+    }
+
 	/**
 	 * Add method
 	 * @param string $name
@@ -313,16 +322,17 @@ protected function _convertListeners()
 
 		$listenersArray = array();
 
-		foreach ($this->_listeners as $k=>$v)
+		foreach ($this->_listeners as $name=>$code)
 		{
-			if($k==='handler' && $this->_config->isValidProperty('handler'))
+
+			if($name==='handler' && $this->_config->isValidProperty('handler'))
 			{
-				$this->_config->handler = $v;
+				$this->_config->handler = $code;
 				if($this->_config->isValidProperty('scope'))
 				  $this->_config->scope = 'this';
 
 			}else{
-				$listenersArray[] = "'".$k."':".$v;
+				$listenersArray[] = "'".$name."':".$code;
 			}
 		}
 		if(!empty($listenersArray))
diff --git a/dvelum/library/Ext/Property/Form/Field/Tag.php b/dvelum/library/Ext/Property/Form/Field/Tag.php
new file mode 100644
index 00000000..4779aac4
--- /dev/null
+++ b/dvelum/library/Ext/Property/Form/Field/Tag.php
@@ -0,0 +1,23 @@
+_fields))
-		    $this->fields = "[\n".Utils_String::addIndent(implode(',',array_values($this->_fields)))."\n]";
-				
+		{
+//            foreach ($this->_fields as $field)
+//            {
+//                if($field->getConfig()->isValidProperty('mapping') && strlen($field->mapping))
+//                {
+//                    $model = Ext_Code::appendNamespace($field->mapping);
+//                    $field->mapping = $model;
+//                }
+//            }
+            $this->fields = "[\n".Utils_String::addIndent(implode(',',array_values($this->_fields)))."\n]";
+        }
+
 		if($this->_config->isValidProperty('model') && strlen($this->_config->model))
 		{			
 			$model = Ext_Code::appendNamespace($this->_config->model);	
diff --git a/dvelum/library/File.php b/dvelum/library/File.php
index fcb8296b..61738f83 100755
--- a/dvelum/library/File.php
+++ b/dvelum/library/File.php
@@ -61,8 +61,8 @@ static public function getExt($name)
 	static public function fillEndSep($path)
 	{
 		$length = strlen($path);
-		if(!$length || $path[$length - 1] !== DIRECTORY_SEPARATOR)
-			$path .= DIRECTORY_SEPARATOR;
+		if(!$length || $path[$length - 1] !== self::$directorySeparator)
+			$path .= self::$directorySeparator;
 
 		return $path;
 	}
@@ -407,4 +407,4 @@ static public function checkWritePermission(array $files)
 		else
 			return $cantWrite;
 	}
-}
\ No newline at end of file
+}
diff --git a/dvelum/library/Filestorage/Abstract.php b/dvelum/library/Filestorage/Abstract.php
index 9f67397b..576ddc9a 100644
--- a/dvelum/library/Filestorage/Abstract.php
+++ b/dvelum/library/Filestorage/Abstract.php
@@ -41,21 +41,21 @@ public function __construct(Config_Abstract $config)
     	$this->_config = $config;
     }
     /**
-     * Fileupload via POST and FILES
-     * @throws Exception
+     * Upload files from $_POST and $_FILES
+     * @return  boolean | array
      */
     abstract public function upload();
     /**
      * Remove file from storage
      * @param string $fileId
-     * @return boolen
+     * @return boolean
      */
     abstract public function remove($fileId);
 
     /**
      * Add file (copy to storage)
      * @param string $filePath
-     * @param sting $useName, optional set specific file name
+     * @param string $useName, optional set specific file name
      * @throws Exception
      * @return array | boolean false - file info
      */
@@ -86,4 +86,13 @@ public function getConfig()
     {
         return $this->_config;
     }
+
+    /**
+     * Get storage files path
+     * @return mixed
+     */
+    public function getPath()
+    {
+        return $this->_config->get('filepath');
+    }
 }
\ No newline at end of file
diff --git a/dvelum/library/Filestorage/Orm.php b/dvelum/library/Filestorage/Orm.php
index f320f67c..1c8baa1b 100644
--- a/dvelum/library/Filestorage/Orm.php
+++ b/dvelum/library/Filestorage/Orm.php
@@ -74,7 +74,7 @@ public function upload()
         $data = parent::upload();
 
         if(empty($data))
-            return array();
+            return false;
 
         foreach ($data as $k=>&$v)
         {
diff --git a/dvelum/library/Filestorage/Simple.php b/dvelum/library/Filestorage/Simple.php
index fbcba74b..2e2937cb 100644
--- a/dvelum/library/Filestorage/Simple.php
+++ b/dvelum/library/Filestorage/Simple.php
@@ -61,7 +61,7 @@ public function upload()
         }
 
         if(empty($files))
-            return array();
+            return false;
 
         $uploadAdapter = $this->_config->get('uploader');
         $uploaderConfig = $this->_config->get('uploader_config');
@@ -71,7 +71,15 @@ public function upload()
         $uploaded = $uploader->start($files, $path);
 
         if(empty($uploaded))
-            return array();
+        {
+            $errors = $uploader->getErrors();
+            if(!empty($errors)){
+                $this->logError(implode(', ', $errors));
+                return false;
+            }
+
+            return [];
+        }
 
         foreach ($uploaded as $k=>&$v){
             $v['path'] = str_replace($this->_config->get('filepath') , '' , $v['path']);
diff --git a/dvelum/library/Filter.php b/dvelum/library/Filter.php
index 815c18d1..96bf6d54 100644
--- a/dvelum/library/Filter.php
+++ b/dvelum/library/Filter.php
@@ -66,35 +66,37 @@ static public function filterString($string)
 	 */
 	static public function filterValue($filter, $value)
 	{
-		$filter = strtolower ( $filter );
+		$filter = strtolower($filter);
 		switch ($filter) {
 			case 'array' :
-				if (! is_array ( $value ))
-					$value = array ($value );
+				if (!is_array($value))
+					$value = array($value);
 				break;
 			case 'bool' :
 			case 'boolean' :
-				$value = filter_var ( $value, FILTER_VALIDATE_BOOLEAN );
+				$value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
 				break;
 			case 'int' :
 			case 'integer' :
-				$value = intval ( $value );
+				$value = intval($value);
 				break;
 			case 'float' :
 			case 'decimal' :
 			case 'number' :
-				if(self::$_autoConvertFloatSeparator)
-					$value = str_replace(',', '.', $value);
-				$value = floatval ( $value );
+                $value = filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_THOUSAND);
+                if(is_string($value) && self::$_autoConvertFloatSeparator){
+                    $value = str_replace(',', '.', $value);
+                }
+				$value = floatval($value);
 				break;
 			case 'str' :
 			case 'string' :
 			case 'text' :
-				$value = filter_var ( trim ( $value ), FILTER_SANITIZE_STRING );
+				$value = trim(filter_var($value, FILTER_SANITIZE_STRING));
 				break;
 			
 			case 'cleaned_string' :
-				$value = filter_var ( trim ( $value ), FILTER_SANITIZE_FULL_SPECIAL_CHARS );
+				$value = trim(filter_var($value, FILTER_SANITIZE_FULL_SPECIAL_CHARS));
 				break;
 			
 			case 'email' :
@@ -102,7 +104,7 @@ static public function filterValue($filter, $value)
 				break;
 				
 			case 'url' :
-				$value = filter_var($value , FILTER_SANITIZE_URL);
+				$value = filter_var($value, FILTER_SANITIZE_URL);
 				break;
 				  
 			case 'raw' :
diff --git a/dvelum/library/Model.php b/dvelum/library/Model.php
index f0255612..c72d7976 100644
--- a/dvelum/library/Model.php
+++ b/dvelum/library/Model.php
@@ -806,12 +806,12 @@ public function getTitle(Db_Object $object)
     /**
      * Delete record
      * @param integer $recordId record ID
-     * @param boolean $log — log changes
+     * @return  boolean
      */
-    public function remove($recordId , $log = true)
+    public function remove($recordId)
     {
         $object = new Db_Object($this->_name , $recordId);
-        if(self::_getObjectsStore()->delete($object , $log))
+        if(self::_getObjectsStore()->delete($object))
             return true;
         else
             return false;
@@ -853,12 +853,25 @@ protected function _queryAddJoins($sql , array $joins)
     }
 
     /**
-     * Add Like where couse for query
+     * Add search text
      * @param Db_Select | Zend_Db_Select $sql
      * @param string $query
      * @param string $alias - table name alias, optional
+     * @deprecated
      */
     protected function _queryAddQuery($sql , $query, $alias = false)
+    {
+        $this->queryAddSearchString($sql , $query, $alias);
+    }
+
+    /**
+     *  Add search text
+     * @param Db_Select | Zend_Db_Select $sql
+     * @param string $search
+     * @param string $alias - table name alias for search fields, optional
+     * @param string $mathchType - match template %[s]% or %[s] or [s]%, default %[s]%
+     */
+    public function queryAddSearchString($sql , $search, $alias = false, $mathchType='%[s]%')
     {
         if(!$alias){
             $alias = $this->table();
@@ -871,9 +884,11 @@ protected function _queryAddQuery($sql , $query, $alias = false)
 
         $q = array();
 
+        $search = str_replace('[s]', $search, $mathchType);
+
         foreach($searchFields as $v)
         {
-            $q[] = $alias . "." . $v . " LIKE(". $this->_db->quote('%'.$query.'%').")";
+            $q[] = $alias . "." . $v . " LIKE(". $this->_db->quote($search).")";
         }
 
         $sql->where('('. implode(' OR ', $q).')');
diff --git a/dvelum/library/Resource.php b/dvelum/library/Resource.php
index 7c8c37a2..0ab64486 100644
--- a/dvelum/library/Resource.php
+++ b/dvelum/library/Resource.php
@@ -119,7 +119,7 @@ public function addJs($file, $order = false, $minified = false, $tag = false)
 	/**
 	 * Add css file to the contentent
 	 * @param string $file
-	 * @param integer $order
+	 * @param integer|bool $order
 	 */
 	public function addCss($file , $order = false)
 	{
@@ -127,8 +127,15 @@ public function addCss($file , $order = false)
 			$file = substr($file, 1);
 
 		$hash = md5($file);
-		if($order === false)
-			$order = sizeof($this->_cssFiles);
+		if($order === false){
+            $order = 0;
+            foreach ($this->_cssFiles as $item){
+                if($item['order']> $order){
+                    $order = $item['order'];
+                }
+            }
+            $order ++;
+        }
 
 		if(!isset($this->_cssFiles[$hash]))
 			$this->_cssFiles[$hash] = array(
@@ -225,9 +232,15 @@ public function includeJs($useMin = false , $compile = false , $tag = false)
 		/*
 		 * Raw files
 		 */
-		if(!empty($this->_rawFiles))
-			foreach($this->_rawFiles as $file)
-				$s .= '' . "\n";
+        if(!empty($this->_rawFiles)){
+            foreach($this->_rawFiles as $file){
+                if(strpos($file,'http')==0){
+                    $s .= '' . "\n";
+                }else{
+                    $s .= '' . "\n";
+                }
+            }
+        }
 
 		$s .=  $this->includeJsByTag($useMin , $compile , $tag);
 		/*
diff --git a/dvelum/library/Upload.php b/dvelum/library/Upload.php
index 16eeeb85..3e30279d 100755
--- a/dvelum/library/Upload.php
+++ b/dvelum/library/Upload.php
@@ -7,6 +7,7 @@ class Upload
 {
 	protected $_config;
 	protected $_uploaders;
+    protected $_errors = [];
 
 	public function __construct(array $config)
 	{
@@ -58,11 +59,15 @@ protected function _identifyType($extension)
 	 */
 	public function start(array $files , $path  , $formUpload = true)
 	{
+	    $this->_errors = [];
+
 		$uploadedFiles = array();
 		foreach($files as $k => $item)
 		{
-			if($item['error'])
-				continue;
+			if(isset($item['error']) && $item['error']){
+			    $this->_errors[] = 'Server upload error';
+                continue;
+            }
 
 			$item['name'] = str_replace(' ' , '_' , $item['name']);
 			$item['name'] = strtolower(preg_replace("/[^A-Za-z0-9_\-\.]/i" , '' , $item['name']));
@@ -77,47 +82,73 @@ public function start(array $files , $path  , $formUpload = true)
 			switch($type)
 			{
 				case 'image' :
-					if(!isset($this->_uploaders['image']))
-						$this->_uploaders['image'] = new Upload_Image($this->_config['image']);
+					if(!isset($this->_uploaders['image'])){
+                        $this->_uploaders['image'] = new Upload_Image($this->_config['image']);
+                    }
+                    /**
+                     * @var Upload_AbstractAdapter $uploader
+                     */
+					$uploader = $this->_uploaders['image'];
 
-					$file = $this->_uploaders['image']->upload($item , $path , $formUpload);
-					if(!empty($file))
-					{
+					$file = $uploader->upload($item , $path , $formUpload);
+
+					if(!empty($file)) {
 						$file['type'] = $type;
 						$file['title'] = $item['title'];
-						if(isset($item['old_name']))
-						  $file['old_name'] = $item['old_name'];
-						else
-						  $file['old_name'] = $item['name'];
-
+						if(isset($item['old_name'])){
+                            $file['old_name'] = $item['old_name'];
+                        } else{
+                            $file['old_name'] = $item['name'];
+                        }
 						$uploadedFiles[] = $file;
-					}
+					}else{
+                        if(!empty($uploader->getError())){
+                            $this->_errors[] = $uploader->getError();
+                        }
+                    }
 					break;
 
 				case 'audio' :
 				case 'video' :
 				case 'file' :
-					if(!isset($this->_uploaders['file']))
-						$this->_uploaders['file'] = new Upload_File($this->_config[$type]);
-
-					$file = $this->_uploaders['file']->upload($item , $path , $formUpload);
+					if(!isset($this->_uploaders['file'])){
+                        $this->_uploaders['file'] = new Upload_File($this->_config[$type]);
+                    }
+                    /**
+                     * @var Upload_AbstractAdapter $uploader
+                     */
+                    $uploader = $this->_uploaders['file'];
+                    $file = $uploader->upload($item , $path , $formUpload);
 
 					if(!empty($file))
 					{
 						$file['type'] = $type;
 						$file['title'] = $item['title'];
 
-						if(isset($item['old_name']))
-						  $file['old_name'] = $item['old_name'];
-						else
-						  $file['old_name'] = $item['name'];
-
+						if(isset($item['old_name'])){
+                            $file['old_name'] = $item['old_name'];
+                        } else{
+                            $file['old_name'] = $item['name'];
+                        }
 						$uploadedFiles[] = $file;
-					}
-
+					}else{
+                        if(!empty($uploader->getError())){
+                            $this->_errors[] = $uploader->getError();
+                        }
+                    }
 					break;
 			}
 		}
+
 		return $uploadedFiles;
 	}
+
+    /**
+     * Get upload errors
+     * @return array
+     */
+	public function getErrors()
+    {
+       return $this->_errors;
+    }
 }
\ No newline at end of file
diff --git a/dvelum/library/Upload/AbstractAdapter.php b/dvelum/library/Upload/AbstractAdapter.php
new file mode 100644
index 00000000..7ccdb5df
--- /dev/null
+++ b/dvelum/library/Upload/AbstractAdapter.php
@@ -0,0 +1,41 @@
+.
+ */
+abstract class Upload_AbstractAdapter
+{
+    protected $_error = '';
+    protected $_config;
+
+    public function __construct(array $config)
+    {
+        $this->_config = $config;
+    }
+
+    public function getError()
+    {
+        return $this->_error;
+    }
+
+    /**
+     * Upload file
+     * @param array $data- $_FILES array item
+     * @param boolean $formUpload  - optional, default true
+     * @return array / false on error
+     */
+    abstract public function upload(array $data , $path , $formUpload = true);
+}
\ No newline at end of file
diff --git a/dvelum/library/Upload/File.php b/dvelum/library/Upload/File.php
index 41ad9542..fb47f549 100755
--- a/dvelum/library/Upload/File.php
+++ b/dvelum/library/Upload/File.php
@@ -4,15 +4,8 @@
  * @package Upload
  * @author Kirill Egorov
  */
-class Upload_File
+class Upload_File extends Upload_AbstractAdapter
 {
-    protected $_config;
-
-    public function __construct(array $config)
-    {
-        $this->_config = $config;
-    }
-
     /**
      * Upload file
      *
@@ -22,12 +15,18 @@ public function __construct(array $config)
      */
     public function upload(array $data , $path , $formUpload = true)
     {
-        if($data['error'])
+        $this->_error = '';
+
+        if($data['error']){
+            $this->_error = 'Server upload error';
             return false;
+        }
 
         if(isset($this->_config['max_file_size']) && ($this->_config['max_file_size'])){
-            if($data['size'] > $this->_config['max_file_size'])
+            if($data['size'] > $this->_config['max_file_size']){
+                $this->_error = 'File too large. Check max_file_size option';
                 return false;
+            }
         }
 
         $result = array(
@@ -42,8 +41,11 @@ public function upload(array $data , $path , $formUpload = true)
 
         $ext = File::getExt($name);
 
-        if(!in_array($ext , $this->_config['extensions']))
+        if(!in_array($ext , $this->_config['extensions'])){
+            $this->_error='File extension is not allowed';
             return false;
+        }
+
 
         $namePart = str_replace($ext , '' , $name);
 
@@ -68,6 +70,7 @@ public function upload(array $data , $path , $formUpload = true)
             $renameCount++;
             // limit iterations
             if($renameCount == 100){
+                $this->_error='Cannot rename file. Iterations limit';
                 return false;
             }
         }
@@ -78,13 +81,18 @@ public function upload(array $data , $path , $formUpload = true)
 
         if($formUpload)
         {
-            if(!@move_uploaded_file($data['tmp_name'] , $result['path']))
+            if(!move_uploaded_file($data['tmp_name'] , $result['path'])){
+                $this->_error='move_uploaded_file error';
                 return false;
+            }
+
         }
         else
         {
-            if(!@copy($data['tmp_name'] , $result['path']))
+            if(!copy($data['tmp_name'] , $result['path'])){
+                $this->_error='copy error';
                 return false;
+            }
         }
 
         $result['size'] = $data['size'];
diff --git a/license.txt b/license.txt
index f67c19d4..a95c8692 100644
--- a/license.txt
+++ b/license.txt
@@ -1,5 +1,5 @@
-DVelum 1.0.0 PROFESSIONAL WEB-DEVELOPMENT PLATFORM
-Copyright (C) 2011-2016,  Kirill A Egorov, Andrew Zamotaev, Sergey Leschenko
+DVelum 1.0.2 PROFESSIONAL WEB-DEVELOPMENT PLATFORM
+Copyright (C) 2011-2017,  Kirill A Egorov, Andrew Zamotaev, Sergey Leschenko
 http://dvelum.net/license.html
 
 This version of DVelum is licensed under the terms of the Open Source GPL 3.0 license. 
@@ -15,4 +15,4 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with this program.  If not, see 
\ No newline at end of file
+along with this program. If not, see 
\ No newline at end of file
diff --git a/tests/unit/library/FileTest.php b/tests/unit/library/FileTest.php
index 55093e42..89ea7169 100644
--- a/tests/unit/library/FileTest.php
+++ b/tests/unit/library/FileTest.php
@@ -22,7 +22,7 @@ public function testFillEndSep()
     public function testRmdirRecursive()
     {
         $dir = './temp/unit/'.date('Y').'/'.date('m').'/'.date('d');
-        $this->assertTrue(mkdir($dir , 0777, true));
+        $this->assertTrue(mkdir($dir , 0664, true));
         $this->assertTrue((boolean)file_put_contents($dir.'/test.txt','test'));
         $this->assertTrue(File::rmdirRecursive('./temp/unit/'.date('Y'),true));
         $this->assertTrue(!file_exists('./temp/unit/'.date('Y')));
diff --git a/tests/unit/phpunit.xml b/tests/unit/phpunit.xml
index 4fc2bce4..03001e3d 100644
--- a/tests/unit/phpunit.xml
+++ b/tests/unit/phpunit.xml
@@ -20,19 +20,18 @@
         
             /usr/share/php
             ../../test
-            ../../www/system/library/Zend
-            ../../www/system/library/Code/Js
-            ../../www/system/packages
+            ../../vendor
         
         
-            ../../www/system/app
-            ../../www/system/library
+            ../../dvelum/app
+            ../../dvelum/library
+            ../../application/controllers
+            ../../application/library
+            ../../application/models
             
                 ./
                 ./bootstrap.php
-				../../www/system/library/Zend
-            	../../www/system/library/Code/Js
-            	../../www/system/packages
+            	../../dvelum/library/Code/Js
             
         
     
diff --git a/www/css/system/style.css b/www/css/system/style.css
index 989f06a0..767cbe90 100644
--- a/www/css/system/style.css
+++ b/www/css/system/style.css
@@ -449,4 +449,16 @@ div.module-target{
 }
 #msg-div .msg p {
     margin: 0;
+}
+
+.hint-label {
+    background: #f67d12;
+    display: inline-block;
+    padding: 4px 6px;
+    color: #ffffff;
+    border-radius: 3px;
+    font-size: 11px;
+    font-weight: bold;
+    margin-right: 10px;
+    line-height: 1
 }
\ No newline at end of file
diff --git a/www/i/system/archive.png b/www/i/system/archive.png
new file mode 100644
index 00000000..7e5d49a6
Binary files /dev/null and b/www/i/system/archive.png differ
diff --git a/www/i/system/designer/tag.png b/www/i/system/designer/tag.png
new file mode 100644
index 00000000..376e5820
Binary files /dev/null and b/www/i/system/designer/tag.png differ
diff --git a/www/i/system/doc.png b/www/i/system/doc.png
new file mode 100644
index 00000000..f4d5bfd1
Binary files /dev/null and b/www/i/system/doc.png differ
diff --git a/www/i/system/excel.png b/www/i/system/excel.png
new file mode 100644
index 00000000..dc9876e0
Binary files /dev/null and b/www/i/system/excel.png differ
diff --git a/www/i/system/pdf.png b/www/i/system/pdf.png
new file mode 100644
index 00000000..43ca4d26
Binary files /dev/null and b/www/i/system/pdf.png differ
diff --git a/www/js/app/system/Designer.js b/www/js/app/system/Designer.js
index 00e2cc58..24c36076 100644
--- a/www/js/app/system/Designer.js
+++ b/www/js/app/system/Designer.js
@@ -12,7 +12,7 @@ if(message.command&&message.params){this.runCommand(message.command,message.para
 {switch(command){case'windowSizeChanged':designer.msg(desLang.success,desLang.windowSizeChanged);break;case'columnSizeChanged':designer.msg(desLang.success,desLang.columnSizeChanged);break;case'columnMoved':designer.msg(desLang.success,desLang.columnMoved);break;}},initLayout:function()
 {this.layout='border';this.projectItems=Ext.create('designer.objects.Manager',{region:'north',split:true,height:300,collapsible:true,controllerUrl:app.createUrl([designer.controllerUrl,'objects','']),listeners:{itemSelected:{fn:this.showProperties,scope:this},dataChanged:{fn:this.refreshCodeframe,scope:this},objectRemoved:{fn:function(){this.propertiesPanel.removeAll();this.propertiesPanel.setTitle('');},scope:this}}});this.propertiesPanel=Ext.create('Ext.Panel',{region:'center',split:true,layout:'fit',title:desLang.properties,collapsible:false,border:false});this.rightPanel=Ext.create('Ext.Panel',{region:'east',title:desLang.projectTree,split:true,minWidth:250,width:350,collapsible:true,layout:'border',items:[this.projectItems,this.propertiesPanel]});this.centerPanel=Ext.create('Ext.Panel',{region:'center',border:false,split:true,layout:'fit'});this.codeEditor=Ext.create('designer.codeEditor',{title:desLang.codeEditor,disabled:true,controllerUrl:app.createUrl([designer.controllerUrl,'actionjs',''])});this.eventsEditor=Ext.create('designer.eventsEditor',{title:desLang.eventsEditor,disabled:true,controllerUrl:app.createUrl([designer.controllerUrl,'events','']),listeners:{'eventsUpdated':{fn:function(){this.onChange();if(!Ext.isEmpty(this.activePropertyPanel)){this.activePropertyPanel.refreshEvents();}},scope:this}}});this.methodsEditor=Ext.create('designer.methodsEditor',{title:desLang.methodsEditor,disabled:true,controllerUrl:app.createUrl([designer.controllerUrl,'methods','']),listeners:{'methodsUpdated':{fn:function(){this.onChange();if(!Ext.isEmpty(this.activePropertyPanel)){this.activePropertyPanel.refreshMethods();}},scope:this}}});var bottomTabs=Ext.create('Ext.tab.Panel',{deferredRender:false,frame:false,layout:'fit',items:[this.codeEditor,this.eventsEditor,this.methodsEditor],listeners:{activate:{fn:function(tab,opt){this.codeEditor.syncEditor();},scope:this}}});this.contentContainer=Ext.create('Ext.Container',{layout:'card',activeItem:0,deferredRender:false,header:false,region:'center',items:[this.centerPanel,bottomTabs]});this.items=[this.rightPanel,this.contentContainer];},initToolbars:function()
 {var pressed=app.cookieProvider.get('autoRefresh');if(pressed===undefined){pressed=true;}
-this.autoRefreshSwitch=Ext.create('Ext.button.Button',{tooltip:desLang.autoRefresh,iconCls:'autoRefreshIcon',showType:'loaded',scope:this,enableToggle:true,pressed:pressed,listeners:{scope:this,toggle:function(btn,pressed){app.cookieProvider.set('autoRefresh',pressed);}}});this.viewSwitch=Ext.create('Ext.button.Button',{iconCls:'viewInterfaceIcon',text:desLang.layout,showType:'loaded',scope:this,enableToggle:true,pressed:true,toggleGroup:'viewTypeGroup',scope:this,toggleHandler:function(btn,status){if(status){this.contentContainer.getLayout().setActiveItem(0);if(this.needRefresh){this.refreshCodeframe(true);}}else{this.contentContainer.getLayout().setActiveItem(1);}}});this.codeSwitch=Ext.create('Ext.button.Button',{iconCls:'viewCodeIcon',text:desLang.code,showType:'loaded',scope:this,enableToggle:true,pressed:false,toggleGroup:'viewTypeGroup'});this.projectPathLabel=Ext.create('Ext.toolbar.TextItem',{});this.dockedItems=[{xtype:'toolbar',dock:'left',defaults:{showType:'loaded',iconCls:'add16',textAlign:'left',scope:this,handler:this.addObject},items:[{text:desLang.container,iconCls:'containerIcon',tooltip:desLang.add+' '+desLang.container,oClass:'container'},{text:desLang.panel,iconCls:'panelIcon',tooltip:desLang.add+' '+desLang.panel,oClass:'panel'},{text:desLang.tabPanel,tooltip:desLang.add+' '+desLang.tabPanel,iconCls:'tabIcon',oClass:'tabpanel'},{text:desLang.grid,iconCls:'gridIcon',tooltip:desLang.add+' '+desLang.grid,oClass:'grid'},{text:desLang.toolbar,iconCls:'toolbarPanelIcon',tooltip:desLang.add+' '+desLang.toolbar,oClass:'',handler:false,menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},defaults:{scope:this,handler:this.addObject},items:[{text:'Panel',iconCls:'toolbarPanelIcon',oClass:'Toolbar',showType:'loaded'},{text:'Separator',iconCls:'toolbarSeparatorIcon',oClass:'Toolbar_Separator',showType:'loaded'},{text:'Spacer',iconCls:'toolbarSpacerIcon',oClass:'Toolbar_Spacer',showType:'loaded'},{text:'Fill',iconCls:'toolbarFillIcon',tooltip:desLang.tbFillDescription,oClass:'Toolbar_Fill',showType:'loaded'},{text:'Text Item',iconCls:'toolbarTextitemIcon',oClass:'Toolbar_Textitem',showType:'loaded'},{text:desLang.pagingToolbar,iconCls:'pagingIcon',tooltip:desLang.add+' '+desLang.pagingToolbar,oClass:'Toolbar_Paging',showType:'loaded'}]})},{text:desLang.menu,iconCls:'menuIcon',tooltip:desLang.add+' '+desLang.menu,oClass:'',handler:false,menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},defaults:{scope:this,handler:this.addObject},items:[{text:'Item',iconCls:'toolbarTextitemIcon',oClass:'Menu_Item',showType:'loaded'},{text:'Separator',iconCls:'menuSeparatorIcon',oClass:'Menu_Separator',showType:'loaded'},{text:'Check Item',iconCls:'checkboxIcon',oClass:'Menu_Checkitem',showType:'loaded'},{text:'Date Picker',iconCls:'dateIcon',oClass:'Menu_Datepicker',showType:'loaded'},{text:'Color Picker',iconCls:'colorPickerIcon',oClass:'Menu_Colorpicker',showType:'loaded'}]})},{text:desLang.form,iconCls:'formIcon',oClass:'',handler:false,menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},defaults:{scope:this,handler:this.addObject},items:[{text:desLang.formPanel,iconCls:'formIcon',tooltip:desLang.add+' '+desLang.form,oClass:'form',showType:'loaded'},{text:'Text',iconCls:'textFieldIcon',oClass:'Form_Field_Text',showType:'loaded'},{text:'Number',iconCls:'textFieldIcon',oClass:'Form_Field_Number',showType:'loaded'},{text:'Hidden',iconCls:'hiddenFieldIcon',showType:'loaded',oClass:'Form_Field_Hidden'},{text:'Checkbox',iconCls:'checkboxIcon',oClass:'Form_Field_Checkbox',showType:'loaded'},{text:'Textarea',iconCls:'textareaIcon',tooltip:desLang.tbFillDescription,oClass:'Form_Field_Textarea',showType:'loaded'},{text:'Htmleditor',iconCls:'htmlEditorIcon',oClass:'Form_Field_Htmleditor',showType:'loaded'},{text:'File',iconCls:'fileIcon',oClass:'Form_Field_File',showType:'loaded'},{text:'Radio',iconCls:'radioIcon',oClass:'Form_Field_Radio',showType:'loaded'},{text:'Time',iconCls:'clockIcon',oClass:'Form_Field_Time',showType:'loaded'},{text:'Date',iconCls:'dateIcon',oClass:'Form_Field_Date',showType:'loaded'},{text:'Fieldset',iconCls:'fieldsetIcon',oClass:'Form_Fieldset',showType:'loaded'},{text:'Display Field',iconCls:'displayfieldIcon',oClass:'Form_Field_Display',showType:'loaded'},{text:'Field Container',iconCls:'fieldContainerIcon',oClass:'Form_Fieldcontainer',showType:'loaded'},{text:'Checkbox group',iconCls:'checkboxGroupIcon',oClass:'Form_Checkboxgroup',showType:'loaded'},{text:'Radio group',iconCls:'radioGroupIcon',oClass:'Form_Radiogroup',showType:'loaded'},{text:'Combobox',iconCls:'comboboxFieldIcon',showType:'loaded',oClass:'Form_Field_Combobox'}]})},{text:desLang.buttons,iconCls:'buttonIcon',tooltip:desLang.add+' '+desLang.buttons,oClass:'',handler:false,menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},defaults:{scope:this,handler:this.addObject},items:[{text:desLang.button,iconCls:'buttonIcon',tooltip:desLang.add+' '+desLang.button,oClass:'Button',showType:'loaded'},{text:desLang.splitButton,iconCls:'buttonSplitIcon',tooltip:desLang.add+' '+desLang.splitButton,oClass:'Button_Split',showType:'loaded'},{text:desLang.buttonGroup,iconCls:'buttonGroupIcon',tooltip:desLang.add+' '+desLang.buttonGroup,oClass:'Buttongroup',showType:'loaded'}]})},{text:desLang.tree,iconCls:'treeIcon',tooltip:desLang.add+' '+desLang.tree,oClass:'tree'},{text:'Image',iconCls:'imageIcon',tooltip:desLang.add+' '+desLang.image,oClass:'image'},{text:desLang.view,iconCls:'viewViewIcon',tooltip:desLang.add+' '+desLang.view,oClass:'view'},'-',{text:desLang.window,iconCls:'windowIcon',tooltip:desLang.add+' '+desLang.window,oClass:'window'},'-',{text:desLang.store,iconCls:'storeIcon',tooltip:desLang.add+' '+desLang.store,oClass:'Data_Store'},{text:desLang.treeStore,iconCls:'storeIcon',tooltip:desLang.add+' '+desLang.treeStore,oClass:'Data_Store_Tree'},'-',{text:desLang.model,iconCls:'modelIcon',tooltip:desLang.add+' '+desLang.model,oClass:'Model'},'-',{text:desLang.components,iconCls:'panelIcon',oClass:'',showType:'loaded',handler:false,menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},defaults:{scope:this,handler:this.addObject},items:[{text:'CRUD Window',iconCls:'objectWindowIcon',oClass:'Component_Window_System_Crud',showType:'loaded'},{text:'CRUD VC Window',iconCls:'objectWindowIcon',oClass:'Component_Window_System_Crud_Vc',showType:'loaded'},{text:desLang.field,showType:'loaded',iconCls:'textFieldIcon',menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},defaults:{scope:this,handler:this.addObject},items:[{text:desLang.searchField,iconCls:'textFieldIcon',oClass:'Component_Field_System_Searchfield',showType:'loaded'},{text:desLang.dictionaryField,iconCls:'comboboxFieldIcon',oClass:'Component_Field_System_Dictionary',showType:'loaded'},{text:desLang.mediaHtmlField,iconCls:'textMediaFieldIcon',oClass:'Component_Field_System_Medialibhtml',showType:'loaded'},{text:desLang.mediaItemField,iconCls:'resourceFieldIcon',oClass:'Component_Field_System_Medialibitem',showType:'loaded'},{text:desLang.relatedItemsGrid,iconCls:'gridIcon',oClass:'Component_Field_System_Related',showType:'loaded'},{text:desLang.objectLinkField,iconCls:'olinkIcon',oClass:'Component_Field_System_Objectlink',showType:'loaded'},{text:desLang.objectsListPanel,iconCls:'gridIcon',oClass:'Component_Field_System_Objectslist',showType:'loaded'}]})},{text:desLang.storeFilter,handler:this.addObject,oClass:'Component_Filter',showType:'loaded'}]})},{text:desLang.addInstance,iconCls:'containerIcon',oClass:'',showType:'loaded',tooltip:desLang.addInstanceTip,handler:this.addInstance,scope:this},'-',{text:desLang.templates,iconCls:'containerIcon',oClass:'',showType:'loaded',tooltip:desLang.componentTemplates,scope:this,handler:false,menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},defaults:{scope:this,handler:this.addTemplateObject},items:componentTemplates})}]},{xtype:'toolbar',dock:'top',items:[{text:desLang.layout,showType:'all',menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},items:[{text:desLang.newInterface,iconCls:'newIcon',scope:this,handler:this.createProject,showType:'empty'},{text:desLang.load,iconCls:'openIcon',scope:this,handler:this.selectProject,showType:'empty'},{text:desLang.save,iconCls:'saveIcon',handler:this.saveProject,scope:this,showType:'loaded'},{text:desLang.close,iconCls:'exitIcon',scope:this,handler:this.closeProject,showType:'loaded'}]})},{tooltip:desLang.save,iconCls:'saveIcon',handler:this.saveProject,scope:this,showType:'loaded'},'-',{tooltip:desLang.refreshView,iconCls:'refreshIcon',showType:'loaded',scope:this,handler:function(){this.onChange(true);}},'-',this.autoRefreshSwitch,'-',desLang.viewMode+' :',this.viewSwitch,' / ',this.codeSwitch,{iconCls:'jsIcon',showType:'loaded',tooltip:desLang.showProjectCode,scope:this,handler:this.showProjectCode},{iconCls:'debugIcon',showType:'loaded',tooltip:desLang.showProjectContent,href:app.root+'debugger'},'-',{iconCls:'storeIcon',text:desLang.dbConnections,handler:function(){Ext.create('app.orm.connections.Window',{dbConfigs:dbConfigsList,controllerUrl:app.createUrl([app.admin,'orm','connections',''])}).show();},showType:'all'},{iconCls:'configureIcon',text:desLang.projectConfig,showType:'loaded',handler:function(){Ext.create('designer.configWindow',{controllerUrl:designer.controllerUrl,listeners:{dataSaved:{fn:this.onChange,scope:this}}}).show();}},'-',{text:desLang.relatedProjectItems,showType:'loaded',handler:this.showRelatedProjectItems,scope:this},'-',{text:desLang.backToAdminInterface,showType:'all',href:app.createUrl([app.admin]),hrefTarget:'_self'},'-','->',this.projectPathLabel]}];},initFrame:function(){var contentEl=this.centerPanel.body;this.activeFrame=contentEl.appendChild({tag:'iframe',cls:'viewFrame',id:'viewFrame1'});this.activeFrame.addListener('load',function(){contentEl.unmask();},this);},clearFrame:function(){this.activeFrame.dom.src='';},onChange:function(force){this.loadInterface(force);},loadInterface:function(force){this.projectItems.loadInfo();this.refreshCodeframe(force);},createProject:function(){Ext.create('app.filesystemWindow',{title:desLang.createProject,controllerUrl:app.createUrl([designer.controllerUrl,'fs','']),viewMode:'create',listeners:{fileCreated:{fn:this.loadProject,scope:this}}}).show();},selectProject:function(){Ext.create('app.filesystemWindow',{title:desLang.selectProject,viewMode:'select',controllerUrl:app.createUrl([designer.controllerUrl,'fs','']),listeners:{fileSelected:{fn:this.loadProject,scope:this}}}).show();},loadProject:function(name){var me=this;me.getEl().mask(appLang.LOADING);Ext.Ajax.request({url:app.createUrl([designer.controllerUrl,'project','load']),method:'post',params:{file:name},success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){me.checkIsLoaded();}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);}
+this.autoRefreshSwitch=Ext.create('Ext.button.Button',{tooltip:desLang.autoRefresh,iconCls:'autoRefreshIcon',showType:'loaded',scope:this,enableToggle:true,pressed:pressed,listeners:{scope:this,toggle:function(btn,pressed){app.cookieProvider.set('autoRefresh',pressed);}}});this.viewSwitch=Ext.create('Ext.button.Button',{iconCls:'viewInterfaceIcon',text:desLang.layout,showType:'loaded',scope:this,enableToggle:true,pressed:true,toggleGroup:'viewTypeGroup',scope:this,toggleHandler:function(btn,status){if(status){this.contentContainer.getLayout().setActiveItem(0);if(this.needRefresh){this.refreshCodeframe(true);}}else{this.contentContainer.getLayout().setActiveItem(1);}}});this.codeSwitch=Ext.create('Ext.button.Button',{iconCls:'viewCodeIcon',text:desLang.code,showType:'loaded',scope:this,enableToggle:true,pressed:false,toggleGroup:'viewTypeGroup'});this.projectPathLabel=Ext.create('Ext.toolbar.TextItem',{});this.dockedItems=[{xtype:'toolbar',dock:'left',defaults:{showType:'loaded',iconCls:'add16',textAlign:'left',scope:this,handler:this.addObject},items:[{text:desLang.container,iconCls:'containerIcon',tooltip:desLang.add+' '+desLang.container,oClass:'container'},{text:desLang.panel,iconCls:'panelIcon',tooltip:desLang.add+' '+desLang.panel,oClass:'panel'},{text:desLang.tabPanel,tooltip:desLang.add+' '+desLang.tabPanel,iconCls:'tabIcon',oClass:'tabpanel'},{text:desLang.grid,iconCls:'gridIcon',tooltip:desLang.add+' '+desLang.grid,oClass:'grid'},{text:desLang.toolbar,iconCls:'toolbarPanelIcon',tooltip:desLang.add+' '+desLang.toolbar,oClass:'',handler:false,menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},defaults:{scope:this,handler:this.addObject},items:[{text:'Panel',iconCls:'toolbarPanelIcon',oClass:'Toolbar',showType:'loaded'},{text:'Separator',iconCls:'toolbarSeparatorIcon',oClass:'Toolbar_Separator',showType:'loaded'},{text:'Spacer',iconCls:'toolbarSpacerIcon',oClass:'Toolbar_Spacer',showType:'loaded'},{text:'Fill',iconCls:'toolbarFillIcon',tooltip:desLang.tbFillDescription,oClass:'Toolbar_Fill',showType:'loaded'},{text:'Text Item',iconCls:'toolbarTextitemIcon',oClass:'Toolbar_Textitem',showType:'loaded'},{text:desLang.pagingToolbar,iconCls:'pagingIcon',tooltip:desLang.add+' '+desLang.pagingToolbar,oClass:'Toolbar_Paging',showType:'loaded'}]})},{text:desLang.menu,iconCls:'menuIcon',tooltip:desLang.add+' '+desLang.menu,oClass:'',handler:false,menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},defaults:{scope:this,handler:this.addObject},items:[{text:'Item',iconCls:'toolbarTextitemIcon',oClass:'Menu_Item',showType:'loaded'},{text:'Separator',iconCls:'menuSeparatorIcon',oClass:'Menu_Separator',showType:'loaded'},{text:'Check Item',iconCls:'checkboxIcon',oClass:'Menu_Checkitem',showType:'loaded'},{text:'Date Picker',iconCls:'dateIcon',oClass:'Menu_Datepicker',showType:'loaded'},{text:'Color Picker',iconCls:'colorPickerIcon',oClass:'Menu_Colorpicker',showType:'loaded'}]})},{text:desLang.form,iconCls:'formIcon',oClass:'',handler:false,menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},defaults:{scope:this,handler:this.addObject},items:[{text:desLang.formPanel,iconCls:'formIcon',tooltip:desLang.add+' '+desLang.form,oClass:'form',showType:'loaded'},{text:'Text',iconCls:'textFieldIcon',oClass:'Form_Field_Text',showType:'loaded'},{text:'Number',iconCls:'textFieldIcon',oClass:'Form_Field_Number',showType:'loaded'},{text:'Hidden',iconCls:'hiddenFieldIcon',showType:'loaded',oClass:'Form_Field_Hidden'},{text:'Checkbox',iconCls:'checkboxIcon',oClass:'Form_Field_Checkbox',showType:'loaded'},{text:'Textarea',iconCls:'textareaIcon',tooltip:desLang.tbFillDescription,oClass:'Form_Field_Textarea',showType:'loaded'},{text:'Htmleditor',iconCls:'htmlEditorIcon',oClass:'Form_Field_Htmleditor',showType:'loaded'},{text:'File',iconCls:'fileIcon',oClass:'Form_Field_File',showType:'loaded'},{text:'Radio',iconCls:'radioIcon',oClass:'Form_Field_Radio',showType:'loaded'},{text:'Time',iconCls:'clockIcon',oClass:'Form_Field_Time',showType:'loaded'},{text:'Date',iconCls:'dateIcon',oClass:'Form_Field_Date',showType:'loaded'},{text:'Fieldset',iconCls:'fieldsetIcon',oClass:'Form_Fieldset',showType:'loaded'},{text:'Display Field',iconCls:'displayfieldIcon',oClass:'Form_Field_Display',showType:'loaded'},{text:'Field Container',iconCls:'fieldContainerIcon',oClass:'Form_Fieldcontainer',showType:'loaded'},{text:'Checkbox group',iconCls:'checkboxGroupIcon',oClass:'Form_Checkboxgroup',showType:'loaded'},{text:'Radio group',iconCls:'radioGroupIcon',oClass:'Form_Radiogroup',showType:'loaded'},{text:'Combobox',iconCls:'comboboxFieldIcon',showType:'loaded',oClass:'Form_Field_Combobox'},{text:'Tag Field',iconCls:'tagIcon',showType:'loaded',oClass:'Form_Field_Tag'}]})},{text:desLang.buttons,iconCls:'buttonIcon',tooltip:desLang.add+' '+desLang.buttons,oClass:'',handler:false,menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},defaults:{scope:this,handler:this.addObject},items:[{text:desLang.button,iconCls:'buttonIcon',tooltip:desLang.add+' '+desLang.button,oClass:'Button',showType:'loaded'},{text:desLang.splitButton,iconCls:'buttonSplitIcon',tooltip:desLang.add+' '+desLang.splitButton,oClass:'Button_Split',showType:'loaded'},{text:desLang.buttonGroup,iconCls:'buttonGroupIcon',tooltip:desLang.add+' '+desLang.buttonGroup,oClass:'Buttongroup',showType:'loaded'}]})},{text:desLang.tree,iconCls:'treeIcon',tooltip:desLang.add+' '+desLang.tree,oClass:'tree'},{text:'Image',iconCls:'imageIcon',tooltip:desLang.add+' '+desLang.image,oClass:'image'},{text:desLang.view,iconCls:'viewViewIcon',tooltip:desLang.add+' '+desLang.view,oClass:'view'},'-',{text:desLang.window,iconCls:'windowIcon',tooltip:desLang.add+' '+desLang.window,oClass:'window'},'-',{text:desLang.store,iconCls:'storeIcon',tooltip:desLang.add+' '+desLang.store,oClass:'Data_Store'},{text:desLang.treeStore,iconCls:'storeIcon',tooltip:desLang.add+' '+desLang.treeStore,oClass:'Data_Store_Tree'},'-',{text:desLang.model,iconCls:'modelIcon',tooltip:desLang.add+' '+desLang.model,oClass:'Model'},'-',{text:desLang.components,iconCls:'panelIcon',oClass:'',showType:'loaded',handler:false,menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},defaults:{scope:this,handler:this.addObject},items:[{text:'CRUD Window',iconCls:'objectWindowIcon',oClass:'Component_Window_System_Crud',showType:'loaded'},{text:'CRUD VC Window',iconCls:'objectWindowIcon',oClass:'Component_Window_System_Crud_Vc',showType:'loaded'},{text:desLang.field,showType:'loaded',iconCls:'textFieldIcon',menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},defaults:{scope:this,handler:this.addObject},items:[{text:desLang.searchField,iconCls:'textFieldIcon',oClass:'Component_Field_System_Searchfield',showType:'loaded'},{text:desLang.dictionaryField,iconCls:'comboboxFieldIcon',oClass:'Component_Field_System_Dictionary',showType:'loaded'},{text:desLang.mediaHtmlField,iconCls:'textMediaFieldIcon',oClass:'Component_Field_System_Medialibhtml',showType:'loaded'},{text:desLang.mediaItemField,iconCls:'resourceFieldIcon',oClass:'Component_Field_System_Medialibitem',showType:'loaded'},{text:desLang.relatedItemsGrid,iconCls:'gridIcon',oClass:'Component_Field_System_Related',showType:'loaded'},{text:desLang.objectLinkField,iconCls:'olinkIcon',oClass:'Component_Field_System_Objectlink',showType:'loaded'},{text:desLang.objectsListPanel,iconCls:'gridIcon',oClass:'Component_Field_System_Objectslist',showType:'loaded'}]})},{text:desLang.storeFilter,handler:this.addObject,oClass:'Component_Filter',showType:'loaded'}]})},{text:desLang.addInstance,iconCls:'containerIcon',oClass:'',showType:'loaded',tooltip:desLang.addInstanceTip,handler:this.addInstance,scope:this},'-',{text:desLang.templates,iconCls:'containerIcon',oClass:'',showType:'loaded',tooltip:desLang.componentTemplates,scope:this,handler:false,menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},defaults:{scope:this,handler:this.addTemplateObject},items:componentTemplates})}]},{xtype:'toolbar',dock:'top',items:[{text:desLang.layout,showType:'all',menu:Ext.create('Ext.menu.Menu',{style:{overflow:'visible'},items:[{text:desLang.newInterface,iconCls:'newIcon',scope:this,handler:this.createProject,showType:'empty'},{text:desLang.load,iconCls:'openIcon',scope:this,handler:this.selectProject,showType:'empty'},{text:desLang.save,iconCls:'saveIcon',handler:this.saveProject,scope:this,showType:'loaded'},{text:desLang.close,iconCls:'exitIcon',scope:this,handler:this.closeProject,showType:'loaded'}]})},{tooltip:desLang.save,iconCls:'saveIcon',handler:this.saveProject,scope:this,showType:'loaded'},'-',{tooltip:desLang.refreshView,iconCls:'refreshIcon',showType:'loaded',scope:this,handler:function(){this.onChange(true);}},'-',this.autoRefreshSwitch,'-',desLang.viewMode+' :',this.viewSwitch,' / ',this.codeSwitch,{iconCls:'jsIcon',showType:'loaded',tooltip:desLang.showProjectCode,scope:this,handler:this.showProjectCode},{iconCls:'debugIcon',showType:'loaded',tooltip:desLang.showProjectContent,href:app.root+'debugger'},'-',{iconCls:'storeIcon',text:desLang.dbConnections,handler:function(){Ext.create('app.orm.connections.Window',{dbConfigs:dbConfigsList,controllerUrl:app.createUrl([app.admin,'orm','connections',''])}).show();},showType:'all'},{iconCls:'configureIcon',text:desLang.projectConfig,showType:'loaded',handler:function(){Ext.create('designer.configWindow',{controllerUrl:designer.controllerUrl,listeners:{dataSaved:{fn:this.onChange,scope:this}}}).show();}},'-',{text:desLang.relatedProjectItems,showType:'loaded',handler:this.showRelatedProjectItems,scope:this},'-',{text:desLang.backToAdminInterface,showType:'all',href:app.createUrl([app.admin]),hrefTarget:'_self'},'-','->',this.projectPathLabel]}];},initFrame:function(){var contentEl=this.centerPanel.body;this.activeFrame=contentEl.appendChild({tag:'iframe',cls:'viewFrame',id:'viewFrame1'});this.activeFrame.addListener('load',function(){contentEl.unmask();},this);},clearFrame:function(){this.activeFrame.dom.src='';},onChange:function(force){this.loadInterface(force);},loadInterface:function(force){this.projectItems.loadInfo();this.refreshCodeframe(force);},createProject:function(){Ext.create('app.filesystemWindow',{title:desLang.createProject,controllerUrl:app.createUrl([designer.controllerUrl,'fs','']),viewMode:'create',listeners:{fileCreated:{fn:this.loadProject,scope:this}}}).show();},selectProject:function(){Ext.create('app.filesystemWindow',{title:desLang.selectProject,viewMode:'select',controllerUrl:app.createUrl([designer.controllerUrl,'fs','']),listeners:{fileSelected:{fn:this.loadProject,scope:this}}}).show();},loadProject:function(name){var me=this;me.getEl().mask(appLang.LOADING);Ext.Ajax.request({url:app.createUrl([designer.controllerUrl,'project','load']),method:'post',params:{file:name},success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){me.checkIsLoaded();}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);}
 me.getEl().unmask();},failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);me.getEl().unmask();}});},checkIsLoaded:function(){Ext.Ajax.request({url:app.createUrl([designer.controllerUrl,'project','checkloaded']),method:'post',scope:this,success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){this.prepareInterface(true);this.onChange();this.projectPathLabel.setText(response.data.file);}else{this.projectPathLabel.setText('');this.prepareInterface(false);}},failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});},saveProject:function(callback)
 {this.codeEditor.saveCode();Ext.Ajax.request({url:app.createUrl([designer.controllerUrl,'project','save']),method:'post',success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){designer.msg(appLang.MESSAGE,desLang.msg_projectSaved);if(typeof callback=='function'){callback();}}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);}},failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});},closeProject:function(){var me=this;Ext.Msg.confirm(appLang.CONFIRMATION,appLang.MSG_SAVE_BEFORE_CLOSE,function(btn){if(btn=='yes'){var callbackFunc=function(){me.prepareInterface(false);me.clearSession();};me.saveProject(callbackFunc);}else{me.clearSession();me.prepareInterface(false);}},this);},prepareInterface:function(asLoaded){Ext.each(this.getDockedItems('toolbar'),function(toolbar){Ext.each(toolbar.query('button , menuitem'),function(item,index){if(item.showType==='all'){return;}
 if(asLoaded){(item.showType=='loaded')?item.enable():item.disable();}else{(item.showType=='loaded')?item.disable():item.enable();}},this);},this);if(asLoaded){this.rightPanel.enable();this.centerPanel.enable();this.codeEditor.enable();this.eventsEditor.enable();this.methodsEditor.enable();this.eventsEditor.getStore().load();this.methodsEditor.getStore().load();this.codeEditor.loadCode();}else{this.codeEditor.disable();this.codeEditor.setValue('');this.eventsEditor.disable();this.methodsEditor.disable();this.projectItems.clearData();this.propertiesPanel.removeAll();this.activePropertyPanel=null;this.projectPathLabel.setText('');this.rightPanel.disable();this.centerPanel.disable();this.clearFrame();}},clearSession:function(){Ext.Ajax.request({url:app.createUrl([designer.controllerUrl,'project','close']),method:'post',failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});},addObject:function(btn){var oClass=btn.oClass;var me=this;var parent=0;if(!oClass.length){return;}
@@ -35,7 +35,7 @@ store.removeAll();var rec=records[0];if(rec.get('leaf')){store.proxy.setExtraPar
 {if(!this.fileTree.getSelectionModel().hasSelection()){return;}
 var selected=this.fileTree.getSelectionModel().getSelection()[0];this.fireEvent('select',selected.get('url'));this.close();return;}
 var sm=this.actionsGrid.getSelectionModel();if(!sm.hasSelection()){Ext.Msg.alert(appLang.MESSAGE,desLang.selectAction);return;}
-var selection=sm.getSelection()[0];this.fireEvent('select',selection.get('url'));this.close();}});Ext.define('designer.urlField',{extend:'Ext.form.field.Text',constructor:function(config){var me=this;config=Ext.apply({extraParams:{},triggers:{select:{hideOnReadOnly:true,cls:'urlTriggerIcon',width:25,handler:function(field,trigger,e){me.showSelectWindow();e.stopEvent();},scope:me}}},config||{});this.callParent(arguments);},showSelectWindow:function(){var me=this;var win=Ext.create('designer.urlWindow',{width:600,height:400,modal:true,onlyController:this.onlyController,controllerUrl:this.controllerUrl,listeners:{scope:me,select:function(url){me.setValue(url);me.fireEvent('select',url);}}});Ext.defer(function(){win.show().toFront();},50);}});Ext.define('designer.iconField',{alias:'widget.urlfield',controllerUrl:'',extend:'Ext.form.field.Text',updateEl:true,constructor:function(config){var me=this;config=Ext.apply({extraParams:{},triggers:{select:{hideOnReadOnly:true,cls:'urlTriggerIcon',width:25,handler:function(){me.showSelectWindow();},scope:me}}},config||{});this.callParent(arguments);},showSelectWindow:function(){var me=this;var win=Ext.create('designer.iconSelectorWindow',{width:600,height:400,controllerUrl:this.controllerUrl,title:desLang.images,listeners:{scope:me,select:function(url){me.setValue(url);me.fireEvent('select',url);}}});Ext.defer(function(){win.show().toFront();},50);}});Ext.define('designer.ormSelectorWindow',{extend:'Ext.Window',title:desLang.importOrm,width:600,height:500,objectsGrid:null,fieldsGrid:null,layout:'border',initComponent:function(){this.objectsGrid=Ext.create('Ext.grid.Panel',{split:true,title:desLang.objects,region:'center',columnLines:true,store:Ext.create('Ext.data.Store',{fields:[{name:'name',type:'string'},{name:'title',type:'string'}],proxy:{url:app.createUrl([designer.controllerUrl,'orm','list','']),type:'ajax',reader:{type:'json',idProperty:'name',rootProperty:'data'}},autoLoad:true,sorters:[{property:'name',direction:'ASC'}]}),columns:[{text:desLang.name,dataIndex:'name',width:100},{text:desLang.title,flex:1,dataIndex:'title'}]});var sm=Ext.create('Ext.selection.CheckboxModel');this.fieldsGrid=Ext.create('Ext.grid.Panel',{split:true,title:desLang.fields,region:'east',selModel:sm,width:350,columnLines:true,store:Ext.create('Ext.data.Store',{fields:[{name:'name',type:'string'},{name:'title',type:'string'},{name:'type',type:'string'}],proxy:{url:app.createUrl([designer.controllerUrl,'orm','fields','']),type:'ajax',extraParams:{object:''},reader:{type:'json',idProperty:'name',rootProperty:'data'}},autoLoad:false,sorters:[{property:'name',direction:'ASC'}]}),columns:[{text:desLang.name,dataIndex:'name',width:100},{text:desLang.title,flex:1,dataIndex:'title'},{text:desLang.type,flex:1,dataIndex:'type'}]});this.objectsGrid.getSelectionModel().on('selectionchange',function(sm){this.fieldsGrid.getStore().removeAll();if(sm.hasSelection()){this.fieldsGrid.getStore().proxy.setExtraParam('object',sm.getSelection()[0].get('name'));this.fieldsGrid.getStore().load();}},this);this.buttons=[{text:desLang.select,scope:this,handler:this.onSelect},{text:desLang.cancel,scope:this,handler:this.close}];this.items=[this.objectsGrid,this.fieldsGrid];this.callParent(arguments);},onSelect:function(){var oSm=this.objectsGrid.getSelectionModel();var fSm=this.fieldsGrid.getSelectionModel();if(!oSm.hasSelection()||!fSm.hasSelection()){Ext.Msg.alert(appLang.MESSAGE,desLang.selectObjectAndFields);return;}
+var selection=sm.getSelection()[0];this.fireEvent('select',selection.get('url'));this.close();}});Ext.define('designer.urlField',{extend:'Ext.form.field.Text',constructor:function(config){var me=this;config=Ext.apply({extraParams:{},triggers:{select:{hideOnReadOnly:true,cls:'urlTriggerIcon',width:25,handler:function(field,trigger,e){me.showSelectWindow();e.stopEvent();},scope:me}}},config||{});this.callParent(arguments);},showSelectWindow:function(){var me=this;var win=Ext.create('designer.urlWindow',{width:600,height:400,modal:true,onlyController:this.onlyController,controllerUrl:this.controllerUrl,listeners:{scope:me,select:function(url){me.setValue(url);me.fireEvent('select',url);}}});Ext.defer(function(){win.show().toFront();},50);}});Ext.define('designer.iconField',{alias:'widget.urlfield',controllerUrl:'',extend:'Ext.form.field.Text',updateEl:true,constructor:function(config){var me=this;config=Ext.apply({extraParams:{},triggers:{select:{hideOnReadOnly:true,cls:'urlTriggerIcon',width:25,handler:function(){me.showSelectWindow();},scope:me}}},config||{});this.callParent(arguments);},showSelectWindow:function(){var me=this;var win=Ext.create('designer.iconSelectorWindow',{width:600,height:400,controllerUrl:this.controllerUrl,title:desLang.images,listeners:{scope:me,select:function(url){me.setValue(url);me.fireEvent('select',url);}}});Ext.defer(function(){win.show().toFront();},50);}});Ext.define('designer.ormSelectorWindow',{extend:'Ext.Window',title:desLang.importOrm,width:700,height:500,objectsGrid:null,fieldsGrid:null,layout:'border',initComponent:function(){var store=Ext.create('Ext.data.Store',{fields:[{name:'name',type:'string'},{name:'title',type:'string'}],proxy:{url:app.createUrl([designer.controllerUrl,'orm','list','']),type:'ajax',reader:{type:'json',idProperty:'name',rootProperty:'data'}},autoLoad:true,sorters:[{property:'name',direction:'ASC'}]});this.objectsGrid=Ext.create('Ext.grid.Panel',{split:true,title:desLang.objects,region:'center',columnLines:true,tbar:['->',Ext.create('SearchPanel',{fieldNames:['name','title'],store:store,local:true})],store:store,columns:[{text:desLang.name,dataIndex:'name',width:100},{text:desLang.title,flex:1,dataIndex:'title'}]});var sm=Ext.create('Ext.selection.CheckboxModel');this.fieldsGrid=Ext.create('Ext.grid.Panel',{split:true,title:desLang.fields,region:'east',selModel:sm,width:350,columnLines:true,store:Ext.create('Ext.data.Store',{fields:[{name:'name',type:'string'},{name:'title',type:'string'},{name:'type',type:'string'}],proxy:{url:app.createUrl([designer.controllerUrl,'orm','fields','']),type:'ajax',extraParams:{object:''},reader:{type:'json',idProperty:'name',rootProperty:'data'}},autoLoad:false,sorters:[{property:'name',direction:'ASC'}]}),columns:[{text:desLang.name,dataIndex:'name',width:100},{text:desLang.title,flex:1,dataIndex:'title'},{text:desLang.type,flex:1,dataIndex:'type'}]});this.objectsGrid.getSelectionModel().on('selectionchange',function(sm){this.fieldsGrid.getStore().removeAll();if(sm.hasSelection()){this.fieldsGrid.getStore().proxy.setExtraParam('object',sm.getSelection()[0].get('name'));this.fieldsGrid.getStore().load();}},this);this.buttons=[{text:desLang.select,scope:this,handler:this.onSelect},{text:desLang.cancel,scope:this,handler:this.close}];this.items=[this.objectsGrid,this.fieldsGrid];this.callParent();this.on('show',function(){app.checkSize(this);},this);},onSelect:function(){var oSm=this.objectsGrid.getSelectionModel();var fSm=this.fieldsGrid.getSelectionModel();if(!oSm.hasSelection()||!fSm.hasSelection()){Ext.Msg.alert(appLang.MESSAGE,desLang.selectObjectAndFields);return;}
 var selection=fSm.getSelection();var names=[];Ext.each(selection,function(item,index){names.push(item.get('name'));},this);this.fireEvent('select',oSm.getSelection()[0].get('name'),names);this.close();}});Ext.define('designer.iconModel',{extend:'Ext.data.Model',fields:[{name:'name'},{name:'url'},{name:'path'}]});Ext.define('designer.iconSelectorWindow',{extend:'Ext.Window',layout:'border',dataTree:null,dataView:null,viewPanel:null,controllerUrl:'',listAction:'imgdirlist',imagesAction:'imglist',width:500,height:300,modal:true,iconWidth:16,iconHeight:16,initComponent:function(){this.dataTree=Ext.create('app.FilesystemTree',{controllerUrl:this.controllerUrl,listAction:this.listAction,region:'west',minWidth:250,width:250,collapsible:true,listeners:{'select':{fn:function(RowModel,record,index,eOpts){var store=this.dataView.getStore();store.proxy.setExtraParam('dir',record.get('id'));store.load();},scope:this}}});this.dataView=Ext.create('Ext.view.View',{store:Ext.create('Ext.data.Store',{model:'designer.iconModel',proxy:{type:'ajax',url:this.controllerUrl+this.imagesAction,reader:{type:'json',rootProperty:'data'},autoLoad:false}}),tpl:['','
','
','{shortName}
','
','
'],multiSelect:false,height:310,trackOver:true,cls:'images-view',overItemCls:'x-item-over',itemSelector:'div.thumb-wrap',emptyText:desLang.noImagesToDisplay,prepareData:function(data){Ext.apply(data,{shortName:Ext.util.Format.ellipsis(data.name,15)});return data;}});this.viewPanel=Ext.create('Ext.Panel',{region:'center',items:[this.dataView],frame:false,bodyCls:'formBody',scrollable:true});this.items=[this.dataTree,this.viewPanel];this.buttons=[{text:desLang.select,scope:this,handler:this.onSelect},{text:desLang.cancel,scope:this,handler:this.close}] this.callParent();},onSelect:function() {var sm=this.dataView.getSelectionModel();if(!sm.hasSelection()){Ext.Msg.alert(appLang.MESSAGE,desLang.selectIcon);return;} @@ -62,7 +62,7 @@ var params=Ext.clone(this.extraParams);params['event']=eventName;var store=this. store.load({scope:this,callback:function(){var index=store.findExact('event',eventName);if(index!=-1){this.editEvent(store.getAt(index));}}});this.fireEvent('eventsUpdated');},failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});},this);},getSearchText:function(){return this.searchField.getValue();},setSearchText:function(text){this.searchField.setValue(text);}});Ext.define('designer.methodsEditor',{extend:'Ext.grid.Panel',scrollable:true,controllerUrl:null,searchField:null,columnLines:true,viewConfig:{stripeRows:true,enableTextSelection:true},initComponent:function(){if(!this.controllerUrl.length){this.controllerUrl=app.createUrl([designer.controllerUrl,'methods','']);} this.store=Ext.create('Ext.data.Store',{fields:[{name:'enabled',type:'boolean'},{name:'object',type:'string'},{name:'method',type:'string'},{name:'params',type:'string'},{name:'has_code',type:'boolean'},{name:'description',type:'string'}],proxy:{type:'ajax',url:this.controllerUrl+'list',reader:{type:'json',rootProperty:'data',idProperty:'id'},simpleSortMode:true},groupField:'object',remoteSort:false,autoLoad:false,sorters:[{property:'object',direction:'DESC'},{property:'method',direction:'DESC'}]});this.searchField=Ext.create('SearchPanel',{store:this.store,local:true,fieldNames:['object','method']});this.tbar=[{iconCls:'refreshIcon',tooltip:desLang.refresh,scope:this,handler:function(){this.store.load();}},this.searchField];this.columns=[{xtype:'actioncolumn',width:20,items:[{iconCls:'editIcon',handler:function(grid,rowIndex,colIndex){var rec=grid.getStore().getAt(rowIndex);this.editMethod(rec);},scope:this}]},{text:desLang.object,dataIndex:'object',width:150},{text:desLang.method,dataIndex:'method',width:150},{text:desLang.params,dataIndex:'params',flex:1},{text:desLang.description,dataIndex:'description',flex:1},{text:desLang.active,dataIndex:'enabled',align:'center',width:40,renderer:app.checkboxRenderer},{xtype:'actioncolumn',width:20,items:[{iconCls:'deleteIcon',handler:function(grid,rowIndex,colIndex){var rec=grid.getStore().getAt(rowIndex);this.removeMethod(rec);},scope:this}]}];this.features=[Ext.create('Ext.grid.feature.Grouping',{groupHeaderTpl:'{name} ({rows.length})',startCollapsed:0,enableGroupingMenu:1,hideGroupedHeader:0})];this.on('itemdblclick',function(view,record,number,event,options){this.editMethod(record);},this);this.callParent();},removeMethod:function(record){Ext.Ajax.request({url:this.controllerUrl+'removemethod',method:'post',scope:this,params:{object:record.get('object'),method:record.get('method')},success:function(response,request){response=Ext.JSON.decode(response.responseText);if(!response.success){Ext.Msg.alert(appLang.MESSAGE,response.msg);return;} designer.msg(appLang.MESSAGE,desLang.msg_methodRemoved);this.getStore().remove(record);this.getStore().commitChanges();this.fireEvent('methodsUpdated');},failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});},editMethod:function(record) -{Ext.create('designer.methodEditorWindow',{controllerUrl:this.controllerUrl,objectName:record.get('object'),methodName:record.get('method'),paramsString:record.get('params'),modal:false,listeners:{'codeSaved':{fn:function(){this.getStore().load();this.fireEvent('methodsUpdated');},scope:this}}}).show();}});Ext.define('designer.methodEditorWindow',{extend:'Ext.Window',modal:false,width:500,height:600,y:20,layout:{type:'vbox',align:'stretch',pack:'start'},maximizable:true,extraParams:null,closeAction:'destroy',controllerUrl:'',objectName:'',methodName:'',paramsString:'',editor:null,constructor:function(){this.extraParams={};this.callParent(arguments);},initComponent:function(){this.extraParams['object']=this.objectName;this.extraParams['method']=this.methodName;this.title=this.objectName+'.'+this.methodName;this.saveButton=Ext.create('Ext.Button',{disabled:true,text:desLang.save,scope:this,handler:this.saveMethod});this.cancelButton=Ext.create('Ext.Button',{text:desLang.close,scope:this,handler:this.close});this.buttons=[this.saveButton,this.cancelButton];this.centerPanel=Ext.create('Ext.Container',{region:'center',layout:'fit'});this.dataForm=Ext.create('Ext.form.Panel',{bodyPadding:5,bodyCls:'formBody',border:false,bosyPadding:5,items:[{xtype:'textarea',labelAlign:'top',name:'description',anchor:'100%',fieldLabel:desLang.description},{xtype:'fieldcontainer',layout:{type:'hbox',pack:'start',align:'stretch'},height:22,items:[{xtype:'textfield',name:'method_name',flex:1,fieldStyle:{border:'none',background:'none',backgroundColor:'#F4F4F4'}},{xtype:'displayfield',value:' : function( '},{xtype:'textfield',name:'params',flex:2,fieldStyle:{border:'none',background:'none',backgroundColor:'#F4F4F4',color:'#5C3BFB'}},{xtype:'displayfield',value:' )'}]}]});this.items=[this.dataForm];this.callParent();this.on('show',this.loadMethodData,this);},loadMethodData:function(){var me=this;Ext.Ajax.request({url:this.controllerUrl+'methoddata',method:'post',scope:this,params:this.extraParams,success:function(response,request){response=Ext.JSON.decode(response.responseText);if(!response.success){Ext.Msg.alert(appLang.MESSAGE,response.msg);return;} +{Ext.create('designer.methodEditorWindow',{controllerUrl:this.controllerUrl,objectName:record.get('object'),methodName:record.get('method'),paramsString:record.get('params'),modal:false,listeners:{'codeSaved':{fn:function(){this.getStore().load();this.fireEvent('methodsUpdated');},scope:this}}}).show();}});Ext.define('designer.methodEditorWindow',{extend:'Ext.Window',modal:false,width:800,height:600,y:20,layout:{type:'vbox',align:'stretch',pack:'start'},maximizable:true,extraParams:null,closeAction:'destroy',controllerUrl:'',objectName:'',methodName:'',paramsString:'',editor:null,constructor:function(){this.extraParams={};this.callParent(arguments);},initComponent:function(){this.extraParams['object']=this.objectName;this.extraParams['method']=this.methodName;this.title=this.objectName+'.'+this.methodName;this.saveButton=Ext.create('Ext.Button',{disabled:true,text:desLang.save,scope:this,handler:this.saveMethod});this.cancelButton=Ext.create('Ext.Button',{text:desLang.close,scope:this,handler:this.close});this.buttons=[this.saveButton,this.cancelButton];this.centerPanel=Ext.create('Ext.Container',{region:'center',layout:'fit'});this.dataForm=Ext.create('Ext.form.Panel',{bodyPadding:5,bodyCls:'formBody',border:false,bosyPadding:5,items:[{xtype:'textarea',labelAlign:'top',name:'description',anchor:'100%',fieldLabel:desLang.description},{xtype:'fieldcontainer',layout:{type:'hbox',pack:'start',align:'stretch'},height:22,items:[{xtype:'textfield',name:'method_name',flex:1,fieldStyle:{border:'none',background:'none',backgroundColor:'#F4F4F4'}},{xtype:'displayfield',value:' : function( '},{xtype:'textfield',name:'params',flex:2,fieldStyle:{border:'none',background:'none',backgroundColor:'#F4F4F4',color:'#5C3BFB'}},{xtype:'displayfield',value:' )'}]}]});this.items=[this.dataForm];this.callParent();this.on('show',function(){this.loadMethodData();app.checkSize(this);Ext.WindowMgr.register(this);Ext.WindowMgr.bringToFront(this);},this);},loadMethodData:function(){var me=this;Ext.Ajax.request({url:this.controllerUrl+'methoddata',method:'post',scope:this,params:this.extraParams,success:function(response,request){response=Ext.JSON.decode(response.responseText);if(!response.success){Ext.Msg.alert(appLang.MESSAGE,response.msg);return;} me.editor=Ext.create('designer.codeEditor',{readOnly:false,showSaveBtn:false,flex:1,sourceCode:response.data['code'],headerText:'{',footerText:'}',extraKeys:{"Ctrl-Space":function(cm){CodeMirror.simpleHint(cm,CodeMirror.javascriptHint);},"Ctrl-S":function(cm){me.saveMethod();},"Ctrl-Z":function(cm){me.editor.undoAction();},"Ctrl-Y":function(cm){me.editor.redoAction();},"Shift-Ctrl-Z":function(cm){me.editor.redoAction();}}});var form=this.dataForm.getForm();form.findField('description').setValue(response.data['description']);form.findField('method_name').setValue(response.data['name']);form.findField('params').setValue(response.data['paramsLine']);this.add(me.editor);this.saveButton.enable();},failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});},saveMethod:function(){var form=this.dataForm.getForm();var code=this.editor.getValue();var params=Ext.clone(this.extraParams);params['code']=code;form.submit({clientValidation:true,waitMsg:appLang.SAVING,method:'post',scope:this,params:params,url:this.controllerUrl+'update',success:function(form,action){if(!action.result.success){Ext.Msg.alert(appLang.MESSAGE,action.result.msg);}else{designer.msg(appLang.MESSAGE,desLang.msg_codeSaved);this.fireEvent('codeSaved');this.extraParams['method']=form.findField('method_name').getValue();this.methodName=this.extraParams['method'];}},failure:app.formFailure});}});Ext.define('designer.methodsModel',{extend:'Ext.data.Model',fields:[{name:'object',type:'string'},{name:'method',type:'string'},{name:'params',type:'string'},{name:'has_code',type:'boolean'}],idProperty:'method'});Ext.define('designer.methodsPanel',{extend:'Ext.grid.Panel',objectName:'',controllerUrl:'',columnLines:true,searchField:null,addButton:null,autoLoadData:true,extraParams:null,searchField:false,constructor:function(config){Ext.apply({extraParams:{}},config||{});this.callParent(arguments);},initComponent:function() {if(!this.controllerUrl.length){this.controllerUrl=app.createUrl([designer.controllerUrl,'methods','']);} this.extraParams['object']=this.objectName;this.store=Ext.create('Ext.data.Store',{model:'designer.methodsModel',proxy:{type:'ajax',url:this.controllerUrl+'objectmethods',reader:{type:'json',rootProperty:'data'},extraParams:this.extraParams,simpleSortMode:true},remoteSort:false,autoLoad:this.autoLoadData,sorters:[{property:'object',direction:'DESC'},{property:'method',direction:'DESC'}]});this.searchField=Ext.create('SearchPanel',{store:this.store,local:true,width:130,hideLabel:true,fieldNames:['method']});this.addButton=Ext.create('Ext.Button',{iconCls:'addIcon',text:desLang.addMethod,scope:this,handler:this.addMethod});this.tbar=[this.addButton,'->',this.searchField];this.columns=[{xtype:'actioncolumn',width:20,items:[{width:20,tooltip:desLang.edit,scope:this,iconCls:'editIcon',handler:function(grid,rowIndex,colIndex){var rec=grid.getStore().getAt(rowIndex);this.editMethod(rec);}}]},{dataIndex:'method',text:desLang.method,flex:1},{dataIndex:'params',text:desLang.params,flex:1},{xtype:'actioncolumn',width:25,items:[{iconCls:'deleteIcon',tooltip:desLang.removeAction,handler:function(grid,rowIndex,colIndex){var rec=grid.getStore().getAt(rowIndex);this.removeMethod(rec);},width:25,scope:this}]}];this.on('celldblclick',function(table,td,cellIndex,record,tr,rowIndex,e,eOpts){this.editMethod(record);},this);this.callParent();},addMethod:function(){Ext.MessageBox.prompt(appLang.MESSAGE,desLang.enterMethodName,function(btn,methodName){if(btn!='ok'){return;} @@ -72,7 +72,7 @@ designer.msg(appLang.MESSAGE,desLang.msg_methodRemoved);this.getStore().remove(r {Ext.create('designer.methodEditorWindow',{controllerUrl:this.controllerUrl,objectName:this.objectName,methodName:record.get('method'),paramsString:record.get('params'),extraParams:this.extraParams,modal:true,listeners:{'codeSaved':{fn:function(){this.getStore().load();this.fireEvent('methodsUpdated');},scope:this}}}).show();},getSearchText:function(){return this.searchField.getValue();},setSearchText:function(text){this.searchField.setValue(text);}});Ext.define('designer.eventsEditorModel',{extend:'Ext.data.Model',fields:[{name:'id',type:'integer'},{name:'object',type:'string'},{name:'event',type:'string'},{name:'params',type:'string'},{name:'is_local',type:'boolean'}],idProperty:'id'});Ext.define('designer.eventsEditor',{extend:'Ext.grid.Panel',scrollable:true,controllerUrl:null,searchField:null,columnLines:true,viewConfig:{stripeRows:true,enableTextSelection:true},initComponent:function(){if(!this.controllerUrl.length){this.controllerUrl=app.createUrl([designer.controllerUrl,'events','']);} this.store=Ext.create('Ext.data.Store',{model:'designer.eventsEditorModel',proxy:{type:'ajax',url:this.controllerUrl+'list',reader:{type:'json',rootProperty:'data',idProperty:'id'},simpleSortMode:true},groupField:'object',remoteSort:false,autoLoad:false,sorters:[{property:'object',direction:'DESC'},{property:'event',direction:'DESC'}]});this.searchField=Ext.create('SearchPanel',{store:this.store,local:true,fieldNames:['object','event']});this.tbar=[{iconCls:'refreshIcon',tooltip:desLang.refresh,scope:this,handler:function(){this.store.load();}},this.searchField];this.columns=[{xtype:'actioncolumn',width:20,items:[{iconCls:'editIcon',handler:function(grid,rowIndex,colIndex){var rec=grid.getStore().getAt(rowIndex);this.editEvent(rec);},scope:this}]},{text:desLang.object,dataIndex:'object',width:150},{text:desLang.event,dataIndex:'event',width:150},{text:desLang.params,dataIndex:'params',flex:1},{xtype:'actioncolumn',width:20,items:[{iconCls:'deleteIcon',handler:function(grid,rowIndex,colIndex){var rec=grid.getStore().getAt(rowIndex);this.removeEvent(rec);},scope:this}]}];this.features=[Ext.create('Ext.grid.feature.Grouping',{groupHeaderTpl:'{name} ({rows.length})',startCollapsed:0,enableGroupingMenu:1,hideGroupedHeader:0})];this.on('itemdblclick',function(view,record,number,event,options){this.editEvent(record);},this);this.callParent();},removeEvent:function(record){Ext.Ajax.request({url:this.controllerUrl+'removeevent',method:'post',scope:this,params:{object:record.get('object'),event:record.get('event')},success:function(response,request){response=Ext.JSON.decode(response.responseText);if(!response.success){Ext.Msg.alert(appLang.MESSAGE,response.msg);return;} designer.msg(appLang.MESSAGE,desLang.msg_listenerRemoved);this.getStore().remove(record);this.getStore().commitChanges();this.fireEvent('eventsUpdated');},failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});},editEvent:function(record) -{Ext.create('designer.eventsEditorWindow',{controllerUrl:this.controllerUrl,objectName:record.get('object'),eventName:record.get('event'),paramsString:record.get('params'),modal:false,listeners:{'codeSaved':{fn:function(){record.set('has_code',true);record.commit();this.fireEvent('eventsUpdated');},scope:this}}}).show();}});Ext.define('designer.eventsEditorWindow',{extend:'Ext.Window',modal:true,width:500,height:600,layout:{type:'vbox',align:'stretch',pack:'start'},autoRender:true,maximizable:true,extraParams:null,closeAction:'destroy',controllerUrl:'',objectName:'',eventName:'',paramsString:'',editor:null,loadedConfig:null,constructor:function(){this.extraParams={};this.callParent(arguments);},initComponent:function(){this.extraParams['object']=this.objectName;this.extraParams['event']=this.eventName;this.title=this.objectName+' on '+this.eventName;this.saveButton=Ext.create('Ext.Button',{disabled:true,text:desLang.save,scope:this,handler:this.saveEvent});this.cancelButton=Ext.create('Ext.Button',{text:desLang.close,scope:this,handler:this.close});this.buttons=[this.saveButton,this.cancelButton];this.dataForm=Ext.create('Ext.form.Panel',{bodyPadding:5,bodyCls:'formBody',border:false,bosyPadding:5,autoHeight:true,split:false,items:[{xtype:'fieldcontainer',layout:{type:'hbox',pack:'start',align:'stretch'},height:22,items:[{xtype:'textfield',name:'new_name',flex:1,fieldStyle:{border:'none',background:'none',backgroundColor:'#F4F4F4'}},{xtype:'displayfield',value:' : function( '},{xtype:'textfield',name:'params',flex:2,fieldStyle:{border:'none',background:'none',backgroundColor:'#F4F4F4',color:'#5C3BFB'}},{xtype:'displayfield',value:' )'}]}]});this.callParent();this.on('show',this.loadCode,this);},loadCode:function(){var me=this;Ext.Ajax.request({url:this.controllerUrl+'eventcode',method:'post',scope:this,params:this.extraParams,success:function(response,request){response=Ext.JSON.decode(response.responseText);if(!response.success){Ext.Msg.alert(appLang.MESSAGE,response.msg);return;} +{Ext.create('designer.eventsEditorWindow',{controllerUrl:this.controllerUrl,objectName:record.get('object'),eventName:record.get('event'),paramsString:record.get('params'),modal:false,listeners:{'codeSaved':{fn:function(){record.set('has_code',true);record.commit();this.fireEvent('eventsUpdated');},scope:this}}}).show();}});Ext.define('designer.eventsEditorWindow',{extend:'Ext.Window',modal:true,width:800,height:600,layout:{type:'vbox',align:'stretch',pack:'start'},autoRender:true,maximizable:true,extraParams:null,closeAction:'destroy',controllerUrl:'',objectName:'',eventName:'',paramsString:'',editor:null,loadedConfig:null,constructor:function(){this.extraParams={};this.callParent(arguments);},initComponent:function(){this.extraParams['object']=this.objectName;this.extraParams['event']=this.eventName;this.title=this.objectName+' on '+this.eventName;this.saveButton=Ext.create('Ext.Button',{disabled:true,text:desLang.save,scope:this,handler:this.saveEvent});this.cancelButton=Ext.create('Ext.Button',{text:desLang.close,scope:this,handler:this.close});this.buttons=[this.saveButton,this.cancelButton];this.dataForm=Ext.create('Ext.form.Panel',{bodyPadding:5,bodyCls:'formBody',border:false,bosyPadding:5,autoHeight:true,split:false,items:[{xtype:'fieldcontainer',layout:{type:'hbox',pack:'start',align:'stretch'},height:22,items:[{xtype:'textfield',name:'new_name',flex:1,fieldStyle:{border:'none',background:'none',backgroundColor:'#F4F4F4'}},{xtype:'displayfield',value:' : function( '},{xtype:'textfield',name:'params',flex:2,fieldStyle:{border:'none',background:'none',backgroundColor:'#F4F4F4',color:'#5C3BFB'}},{xtype:'displayfield',value:' )'}]}]});this.callParent();this.on('show',function(){this.loadCode();app.checkSize(this);Ext.WindowMgr.register(this);Ext.WindowMgr.bringToFront(this);},this);},loadCode:function(){var me=this;Ext.Ajax.request({url:this.controllerUrl+'eventcode',method:'post',scope:this,params:this.extraParams,success:function(response,request){response=Ext.JSON.decode(response.responseText);if(!response.success){Ext.Msg.alert(appLang.MESSAGE,response.msg);return;} this.loadedConfig=response.data;if(!Ext.isEmpty(response.data.is_local)&&response.data.is_local){me.editor=Ext.create('designer.codeEditor',{readOnly:false,showSaveBtn:false,flex:1,sourceCode:response.data.code,headerText:'{',footerText:'}',extraKeys:{"Ctrl-Space":function(cm){CodeMirror.simpleHint(cm,CodeMirror.javascriptHint);},"Ctrl-S":function(cm){me.saveEvent();},"Ctrl-Z":function(cm){me.editor.undoAction();},"Ctrl-Y":function(cm){me.editor.redoAction();},"Shift-Ctrl-Z":function(cm){me.editor.redoAction();}}});var form=this.dataForm.getForm();form.findField('new_name').setValue(response.data['event']);form.findField('params').setValue(response.data['params']);this.add(this.dataForm);}else{me.editor=Ext.create('designer.codeEditor',{readOnly:false,showSaveBtn:false,flex:1,sourceCode:response.data.code,headerText:'function ( '+this.paramsString+' ) { ',footerText:'}',extraKeys:{"Ctrl-Space":function(cm){CodeMirror.simpleHint(cm,CodeMirror.javascriptHint);},"Ctrl-S":function(cm){me.saveEvent();},"Ctrl-Z":function(cm){me.editor.undoAction();},"Ctrl-Y":function(cm){me.editor.redoAction();},"Shift-Ctrl-Z":function(cm){me.editor.redoAction();}}});} this.add(me.editor);this.saveButton.enable();},failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});},saveEvent:function(){var code=this.editor.getValue();var params=Ext.clone(this.extraParams);params['code']=code;if(this.loadedConfig.is_local){var form=this.dataForm.getForm();params['new_name']=form.findField('new_name').getValue();params['params']=form.findField('params').getValue();} Ext.Ajax.request({url:this.controllerUrl+'saveevent',method:'post',scope:this,params:params,success:function(response,request){response=Ext.JSON.decode(response.responseText);if(!response.success){Ext.Msg.alert(appLang.MESSAGE,response.msg);return;} @@ -85,10 +85,10 @@ var me=this;var selected=sm.getSelection()[0];if(selected.get('objClass')=='Dock if(selected.get('objClass')=='Designer_Project_Container'){return;} Ext.Ajax.request({url:this.controllerUrl+'remove',method:'post',params:{'id':selected.get('id')},success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){me.fireEvent('objectRemoved');me.fireEvent('dataChanged');me.getStore().remove(selected);}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);}},failure:app.formFailure});}});Ext.define('designer.objects.Grid',{extend:'Ext.Panel',layout:'fit',dataStore:null,dataGrid:null,initComponent:function() {this.dataGrid=Ext.create('Ext.grid.Panel',{store:this.dataStore,columns:[{text:desLang.name,dataIndex:'title',flex:1},{xtype:'actioncolumn',width:30,items:[{iconCls:'deleteIcon',title:desLang.remove,scope:this,handler:this.removeObject}]}],viewConfig:{stripeRows:false},frame:false,loadMask:true,columnLines:true,scrollable:true,listeners:{'itemclick':{fn:function(view,record,number,event,options){this.fireEvent('itemSelected',record.get('id'),record.get('objClass'),record.get('title'),false);},scope:this}}});this.items=[this.dataGrid];this.callParent(arguments);},getStore:function(){return this.dataStore;},removeObject:function(grid,rowIndex,colIndex) -{var record=grid.getStore().getAt(rowIndex);Ext.Ajax.request({url:this.controllerUrl+'remove',method:'post',params:{'id':record.get('id')},scope:this,success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){grid.getStore().remove(record);this.fireEvent('objectRemoved');this.fireEvent('dataChanged');}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);}},failure:app.formFailure});}});Ext.ns('designer.grid','designer.grid.column');Ext.define('designer.grid.exportFieldsWin',{extend:'Ext.Window',layout:'fit',title:desLang.importStore,width:300,height:250,modal:true,storeName:null,controllerUrl:null,objectName:null,dataGrid:null,dataStore:null,initComponent:function(){this.dataStore=Ext.create('Ext.data.Store',{model:'designer.model.fieldsModel',proxy:{type:'ajax',url:app.createUrl([designer.controllerUrl,'store',''])+'listfields',reader:{type:'json',rootProperty:'data',idProperty:'id'},extraParams:{object:this.storeName},simpleSortMode:true},autoLoad:true});this.dataGrid=Ext.create('Ext.grid.Panel',{border:false,store:this.dataStore,selModel:Ext.create('Ext.selection.CheckboxModel'),columns:[{text:desLang.field,dataIndex:'name',flex:1},{text:desLang.type,dataIndex:'type',width:85}]});this.items=[this.dataGrid];this.buttons=[{text:desLang.select,scope:this,handler:this.addFields},{text:desLang.cancel,scope:this,handler:this.close}];this.callParent(arguments);},addFields:function(){records=this.dataGrid.getSelectionModel().getSelection();var col=[];Ext.each(records,function(record){col.push({name:record.get('name'),type:record.get('type')});},this);Ext.Ajax.request({url:this.controllerUrl+'addcolumns',method:'post',params:{'col':Ext.encode(col),'object':this.objectName},scope:this,success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){this.fireEvent('allSet');}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);}},failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});}});Ext.define('designer.grid.filterOptionsModel',{extend:'Ext.data.Model',fields:[{name:'value',type:'string'}]});Ext.define('designer.grid.filterOptionsWindow',{extend:'Ext.Window',width:500,height:300,layout:'fit',modal:true,title:desLang.items,dataGrid:null,dataStore:null,initialData:[],cellEditing:null,objectName:null,controllerUrl:null,initComponent:function(){this.tbar=[{tooltip:desLang.add,iconCls:'plusIcon',scope:this,handler:this.addRecord}];this.dataStore=Ext.create('Ext.data.Store',{autoDestroy:true,model:'designer.grid.filterOptionsModel',data:this.initialData,autoLoad:false});this.cellEditing=Ext.create('Ext.grid.plugin.CellEditing',{clicksToEdit:1});this.dataGrid=Ext.create('Ext.grid.Panel',{columnLines:true,autoHeight:true,store:this.dataStore,columns:[{text:desLang.value,dataIndex:'value',flex:1,editor:{xtype:'textfield'}},{xtype:'actioncolumn',width:25,sortable:false,menuDisabled:true,align:'center',items:[{iconCls:'deleteIcon',tooltip:desLang.remove,handler:function(grid,row,col){var store=grid.getStore();store.remove(store.getAt(row));}}]}],plugins:[this.cellEditing]});this.items=[this.dataGrid];this.buttons=[{text:desLang.save,handler:this.saveData,scope:this},{text:desLang.close,handler:function(){this.close();},scope:this}];this.callParent(arguments);},addRecord:function(){var count=this.dataStore.getCount();var r=Ext.create('designer.grid.filterOptionsModel',{name:''});this.dataStore.insert(count,r);this.cellEditing.startEditByPosition({row:count,column:0});},saveData:function(){this.dataStore.commitChanges();var options=[];this.dataStore.each(function(record){options.push(record.get('value'));});this.fireEvent('dataChanged','options',Ext.encode(options),true);this.close();}});Ext.define('designer.grid.column.Model',{extend:'Ext.data.Model',fields:[{name:'id',type:'string'},{name:'text',type:'string'},{name:'dataIndex',type:'string'},{name:'type',type:'string'},{name:'editor',type:'string'},{name:'filter',type:'string'},{name:'order',type:'integer'}],idProperty:'id'});Ext.define('designer.grid.column.Window',{extend:'Ext.Window',layout:'border',dataStore:null,dataGrid:null,width:app.checkWidth(900),height:app.checkHeight(650),propertiesPanel:null,objectName:null,storeName:null,controllerUrl:null,cellEditing:null,dataTree:null,dataGrid:null,modal:true,autoLoadData:true,maximizable:true,initComponent:function() +{var record=grid.getStore().getAt(rowIndex);Ext.Ajax.request({url:this.controllerUrl+'remove',method:'post',params:{'id':record.get('id')},scope:this,success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){grid.getStore().remove(record);this.fireEvent('objectRemoved');this.fireEvent('dataChanged');}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);}},failure:app.formFailure});}});Ext.ns('designer.grid','designer.grid.column');Ext.define('designer.grid.exportFieldsWin',{extend:'Ext.Window',layout:'fit',title:desLang.importStore,width:300,height:250,modal:true,storeName:null,controllerUrl:null,objectName:null,dataGrid:null,dataStore:null,initComponent:function(){this.dataStore=Ext.create('Ext.data.Store',{model:'designer.model.fieldsModel',proxy:{type:'ajax',url:app.createUrl([designer.controllerUrl,'store',''])+'allfields',reader:{type:'json',rootProperty:'data',idProperty:'id'},extraParams:{object:this.storeName},simpleSortMode:true},autoLoad:true});this.dataGrid=Ext.create('Ext.grid.Panel',{border:false,store:this.dataStore,selModel:Ext.create('Ext.selection.CheckboxModel'),columns:[{text:desLang.field,dataIndex:'name',flex:1},{text:desLang.type,dataIndex:'type',width:85}]});this.items=[this.dataGrid];this.buttons=[{text:desLang.select,scope:this,handler:this.addFields},{text:desLang.cancel,scope:this,handler:this.close}];this.callParent(arguments);},addFields:function(){records=this.dataGrid.getSelectionModel().getSelection();var col=[];Ext.each(records,function(record){col.push({name:record.get('name'),type:record.get('type')});},this);Ext.Ajax.request({url:this.controllerUrl+'addcolumns',method:'post',params:{'col':Ext.encode(col),'object':this.objectName},scope:this,success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){this.fireEvent('allSet');}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);}},failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});}});Ext.define('designer.grid.filterOptionsModel',{extend:'Ext.data.Model',fields:[{name:'value',type:'string'}]});Ext.define('designer.grid.filterOptionsWindow',{extend:'Ext.Window',width:500,height:300,layout:'fit',modal:true,title:desLang.items,dataGrid:null,dataStore:null,initialData:[],cellEditing:null,objectName:null,controllerUrl:null,initComponent:function(){this.tbar=[{tooltip:desLang.add,iconCls:'plusIcon',scope:this,handler:this.addRecord}];this.dataStore=Ext.create('Ext.data.Store',{autoDestroy:true,model:'designer.grid.filterOptionsModel',data:this.initialData,autoLoad:false});this.cellEditing=Ext.create('Ext.grid.plugin.CellEditing',{clicksToEdit:1});this.dataGrid=Ext.create('Ext.grid.Panel',{columnLines:true,autoHeight:true,store:this.dataStore,columns:[{text:desLang.value,dataIndex:'value',flex:1,editor:{xtype:'textfield'}},{xtype:'actioncolumn',width:25,sortable:false,menuDisabled:true,align:'center',items:[{iconCls:'deleteIcon',tooltip:desLang.remove,handler:function(grid,row,col){var store=grid.getStore();store.remove(store.getAt(row));}}]}],plugins:[this.cellEditing]});this.items=[this.dataGrid];this.buttons=[{text:desLang.save,handler:this.saveData,scope:this},{text:desLang.close,handler:function(){this.close();},scope:this}];this.callParent(arguments);},addRecord:function(){var count=this.dataStore.getCount();var r=Ext.create('designer.grid.filterOptionsModel',{name:''});this.dataStore.insert(count,r);this.cellEditing.startEditByPosition({row:count,column:0});},saveData:function(){this.dataStore.commitChanges();var options=[];this.dataStore.each(function(record){options.push(record.get('value'));});this.fireEvent('dataChanged','options',Ext.encode(options),true);this.close();}});Ext.define('designer.grid.column.Model',{extend:'Ext.data.Model',fields:[{name:'id',type:'string'},{name:'text',type:'string'},{name:'dataIndex',type:'string'},{name:'type',type:'string'},{name:'editor',type:'string'},{name:'filter',type:'string'},{name:'order',type:'integer'}],idProperty:'id'});Ext.define('designer.grid.column.Window',{extend:'Ext.Window',layout:'border',dataStore:null,dataGrid:null,width:app.checkWidth(900),height:app.checkHeight(650),propertiesPanel:null,objectName:null,storeName:null,controllerUrl:null,cellEditing:null,dataTree:null,dataGrid:null,modal:true,autoLoadData:true,maximizable:true,initComponent:function() {this.controllerUrl=app.createUrl([designer.controllerUrl,'grid','']);this.cellEditing=Ext.create('Ext.grid.plugin.CellEditing',{clicksToEdit:1});this.initColumnsGrid();this.initColumnsTree();this.dataGrid.getSelectionModel().on('selectionchange',function(sm,data,opts){if(!sm.hasSelection()){this.propertiesPanel.resetProperties();this.propertiesPanel.refreshEvents();return;} var colId=sm.getSelection()[0].get('id');this.propertiesPanel.setExtraParams({'id':colId,'columnId':colId});this.propertiesPanel.loadProperties();this.propertiesPanel.refreshEvents();},this);this.dataTree.getSelectionModel().on('selectionchange',function(sm){this.cellEditing.completeEdit();if(!sm.hasSelection()){return;} -var recId=sm.getSelection()[0].get('id');var index=this.dataGrid.getStore().findExact('id',recId);if(index!=-1){this.dataGrid.getSelectionModel().select(index);}},this);this.propertiesPanel=Ext.create('designer.properties.GridColumn',{controllerUrl:app.createUrl([designer.controllerUrl,'gridcolumn','']),eventsControllerUrl:app.createUrl([designer.controllerUrl,'gridcolumnevents','']),objectName:this.objectName,autoLoad:false,listeners:{dataSaved:{fn:function(){},scope:this}},title:desLang.properties,layout:'fit',region:'east',showEvents:true,split:true,width:250});this.propertiesPanel.dataGrid.on('propertychange',function(source,recordId,value){if(recordId=='text'){this.treeStore.load();var gridStore=this.dataGrid.getStore();var index=gridStore.findExact('id',recordId);if(index!==-1){var record=gridStore.getAt(index);if(record.get('text')!==value){record.set('text',value);record.commit();}}}},this);this.items=[this.dataTree,this.dataGrid,this.propertiesPanel];this.callParent(arguments);this.reload();this.on('show',function(){app.checkSize(this);});},initColumnsGrid:function(){this.dataStore=Ext.create('Ext.data.Store',{proxy:{type:'ajax',url:this.controllerUrl+'columnlist',reader:{type:'json',idProperty:'id',rootProperty:'data'},extraParams:{object:this.objectName}},model:'designer.grid.column.Model',autoLoad:true,sorters:[{property:'order',direction:'ASC'}]});this.dataGrid=Ext.create('Ext.grid.Panel',{tbar:[{tooltip:desLang.addColumn,iconCls:'plusIcon',scope:this,handler:this.addColumn},{tooltip:desLang.importStore,iconCls:'importDbIcon',scope:this,handler:this.importFieldsFromStore}],store:this.dataStore,region:'center',split:true,title:desLang.columns,columnLines:true,columns:[{xtype:'actioncolumn',width:30,align:'center',items:[{iconCls:'filterIcon',tooltip:desLang.configureFilter,scope:this,handler:function(grid,rowIndex,colIndex){var rec=grid.getStore().getAt(rowIndex);this.showFilterWindow(rec.get('id'));}}]},{xtype:'actioncolumn',width:30,align:'center',items:[{iconCls:'fieldIcon',tooltip:desLang.configureEditor,scope:this,handler:this.showEditorConfig}]},{text:desLang.editor,dataIndex:'editor',width:100},{align:'center',text:desLang.filter,dataIndex:'filter',width:60},{dataIndex:'text',text:desLang.header,flex:1,editor:{xtype:'textfield',flex:1,width:200,editable:true}},{dataIndex:'dataIndex',text:desLang.dataIndex,editable:true,editor:{xtype:'combobox',typeAhead:true,triggerAction:'all',selectOnTab:true,forceSelection:true,valueField:'name',displayField:'name',queryMode:'local',multiSelect:false,store:Ext.create('Ext.data.Store',{model:'designer.model.fieldsModel',proxy:{type:'ajax',url:app.createUrl([designer.controllerUrl,'store',''])+'listfields',reader:{type:'json',rootProperty:'data'},extraParams:{object:this.storeName},simpleSortMode:true},remoteSort:true,autoLoad:true,sorters:[{property:'title',direction:'DESC'}]}),listeners:{select:{fn:function(combo,record){this.propertiesPanel.dataGrid.setProperty('dataIndex',record.get('name'));},scope:this}}}},{dataIndex:'type',text:desLang.type,editable:true,editor:{xtype:'combobox',typeAhead:true,triggerAction:'all',selectOnTab:true,forceSelection:true,store:[['','Simple'],['action','Action'],['date','Date'],['boolean','Boolean'],['number','Number'],['template','Template'],['check','Check']],listeners:{scope:this,select:function(combo,records,eOpts){var columnId=this.dataGrid.getSelectionModel().getLastSelected().get('id');Ext.Ajax.request({url:this.controllerUrl+'changecoltype/',method:'post',params:{'object':this.objectName,'type':records.get('field1'),'columnId':columnId},scope:this,success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){this.propertiesPanel.setExtraParams({'id':columnId,'columnId':columnId});this.propertiesPanel.loadProperties();this.propertiesPanel.refreshEvents();this.propertiesPanel.resetSerchField();}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);return false;}},failure:app.formFailure});}}}},{xtype:'actioncolumn',width:30,align:'center',items:[{iconCls:'deleteIcon',scope:this,tooltip:desLang.remove,handler:this.removeColumn}]}],plugins:[this.cellEditing],listeners:{scope:this,edit:function(editor,o){if(o.field==='text'){this.propertiesPanel.dataGrid.setProperty('text',o.value);} +var recId=sm.getSelection()[0].get('id');var index=this.dataGrid.getStore().findExact('id',recId);if(index!=-1){this.dataGrid.getSelectionModel().select(index);}},this);this.propertiesPanel=Ext.create('designer.properties.GridColumn',{controllerUrl:app.createUrl([designer.controllerUrl,'gridcolumn','']),eventsControllerUrl:app.createUrl([designer.controllerUrl,'gridcolumnevents','']),objectName:this.objectName,autoLoad:false,listeners:{dataSaved:{fn:function(){},scope:this}},title:desLang.properties,layout:'fit',region:'east',showEvents:true,split:true,width:250});this.propertiesPanel.dataGrid.on('propertychange',function(source,recordId,value){if(recordId=='text'){this.treeStore.load();var gridStore=this.dataGrid.getStore();var index=gridStore.findExact('id',recordId);if(index!==-1){var record=gridStore.getAt(index);if(record.get('text')!==value){record.set('text',value);record.commit();}}}},this);this.items=[this.dataTree,this.dataGrid,this.propertiesPanel];this.callParent(arguments);this.reload();this.on('show',function(){app.checkSize(this);});},initColumnsGrid:function(){this.dataStore=Ext.create('Ext.data.Store',{proxy:{type:'ajax',url:this.controllerUrl+'columnlist',reader:{type:'json',idProperty:'id',rootProperty:'data'},extraParams:{object:this.objectName}},model:'designer.grid.column.Model',autoLoad:true,sorters:[{property:'order',direction:'ASC'}]});this.dataGrid=Ext.create('Ext.grid.Panel',{tbar:[{tooltip:desLang.addColumn,iconCls:'plusIcon',scope:this,handler:this.addColumn},{tooltip:desLang.importStore,iconCls:'importDbIcon',scope:this,handler:this.importFieldsFromStore}],store:this.dataStore,region:'center',split:true,title:desLang.columns,columnLines:true,columns:[{xtype:'actioncolumn',width:30,align:'center',items:[{iconCls:'filterIcon',tooltip:desLang.configureFilter,scope:this,handler:function(grid,rowIndex,colIndex){var rec=grid.getStore().getAt(rowIndex);this.showFilterWindow(rec.get('id'));}}]},{xtype:'actioncolumn',width:30,align:'center',items:[{iconCls:'fieldIcon',tooltip:desLang.configureEditor,scope:this,handler:this.showEditorConfig}]},{text:desLang.editor,dataIndex:'editor',width:100},{align:'center',text:desLang.filter,dataIndex:'filter',width:60},{dataIndex:'text',text:desLang.header,flex:1,editor:{xtype:'textfield',flex:1,width:200,editable:true}},{dataIndex:'dataIndex',text:desLang.dataIndex,editable:true,editor:{xtype:'combobox',typeAhead:true,triggerAction:'all',selectOnTab:true,forceSelection:true,valueField:'name',displayField:'name',queryMode:'local',multiSelect:false,store:Ext.create('Ext.data.Store',{model:'designer.model.fieldsModel',proxy:{type:'ajax',url:app.createUrl([designer.controllerUrl,'store',''])+'allfields',reader:{type:'json',rootProperty:'data'},extraParams:{object:this.storeName},simpleSortMode:true},remoteSort:true,autoLoad:true,sorters:[{property:'title',direction:'DESC'}]}),listeners:{select:{fn:function(combo,record){this.propertiesPanel.dataGrid.setProperty('dataIndex',record.get('name'));},scope:this}}}},{dataIndex:'type',text:desLang.type,editable:true,editor:{xtype:'combobox',typeAhead:true,triggerAction:'all',selectOnTab:true,forceSelection:true,store:[['','Simple'],['action','Action'],['date','Date'],['boolean','Boolean'],['number','Number'],['template','Template'],['check','Check']],listeners:{scope:this,select:function(combo,records,eOpts){var columnId=this.dataGrid.getSelectionModel().getLastSelected().get('id');Ext.Ajax.request({url:this.controllerUrl+'changecoltype/',method:'post',params:{'object':this.objectName,'type':records.get('field1'),'columnId':columnId},scope:this,success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){this.propertiesPanel.setExtraParams({'id':columnId,'columnId':columnId});this.propertiesPanel.loadProperties();this.propertiesPanel.refreshEvents();this.propertiesPanel.resetSerchField();}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);return false;}},failure:app.formFailure});}}}},{xtype:'actioncolumn',width:30,align:'center',items:[{iconCls:'deleteIcon',scope:this,tooltip:desLang.remove,handler:this.removeColumn}]}],plugins:[this.cellEditing],listeners:{scope:this,edit:function(editor,o){if(o.field==='text'){this.propertiesPanel.dataGrid.setProperty('text',o.value);} this.dataStore.commitChanges();}}});},initColumnsTree:function() {this.treeStore=Ext.create('Ext.data.TreeStore',{proxy:{type:'ajax',url:this.controllerUrl+'columnlisttree',reader:{type:'json',idProperty:'id'},extraParams:{object:this.objectName},autoLoad:true},root:{text:'/',expanded:true,leaf:false,children:[]},defaultRootId:0,clearOnLoad:true,autoLoad:true});this.dataTree=Ext.create('Ext.tree.Panel',{region:'west',width:200,collapsible:true,collapseMode:'header',collapseFirst:true,clearOnLoad:true,store:this.treeStore,split:true,rootVisible:false,useArrows:false,collapsed:true,title:desLang.columnsTree,viewConfig:{plugins:{ptype:'treeviewdragdrop'},listeners:{drop:{fn:this.sortChanged,scope:this}}}});},sortChanged:function(node,data,overModel,dropPosition,options) {var parentId=0;var parentNode=null;if(dropPosition=='append'){parentId=overModel.get('id');parentNode=overModel;}else{parentId=overModel.parentNode.get('id');parentNode=overModel.parentNode;} @@ -153,13 +153,13 @@ this.tbar.push({icon:app.wwwRoot+'i/system/designer/window-open.png',text:desLan this.tbar.push({iconCls:'importOrmIcon',tooltip:desLang.importOrm,scope:this,handler:this.showImportFromOrm});this.callParent();},showImportFromOrm:function(){this.importWindow=Ext.create('designer.ormSelectorWindow',{listeners:{select:{fn:this.importFields,scope:this}}});this.importWindow.show();},importFields:function(object,fields){this.importWindow.close();Ext.Ajax.request({url:app.createUrl([designer.controllerUrl,'crudwindow','importfields']),method:'post',scope:this,params:{'object':this.objectName,'importobject':object,'importfields[]':fields},success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){this.application.onChange();}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);}},failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});}});Ext.define('designer.properties.Form',{extend:'designer.properties.Panel',importWindow:null,initComponent:function() {this.tbar=[{iconCls:'importOrmIcon',tooltip:desLang.importOrm,scope:this,handler:this.showImportFromOrm},{iconCls:'importDbIcon',tooltip:desLang.importDb,scope:this,handler:this.showImportFromDb}];this.callParent();},showImportFromOrm:function(){this.importWindow=Ext.create('designer.ormSelectorWindow',{listeners:{select:{fn:this.importFields,scope:this}}});this.importWindow.show();},showImportFromDb:function(){this.importWindow=Ext.create('designer.importDBWindow',{listeners:{select:{fn:this.importDbFields,scope:this}}});this.importWindow.show();},importFields:function(object,fields){this.importWindow.close();Ext.Ajax.request({url:app.createUrl([designer.controllerUrl,'form','importfields']),method:'post',scope:this,params:{'object':this.objectName,'importobject':object,'importfields[]':fields},success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){this.fireEvent('objectsUpdated');}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);}},failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});},importDbFields:function(fields,connection,table,contype){this.importWindow.close();Ext.Ajax.request({url:app.createUrl([designer.controllerUrl,'form','importdbfields']),method:'post',scope:this,params:{'object':this.objectName,'connection':connection,'table':table,'type':contype,'importfields[]':fields},success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){this.fireEvent('objectsUpdated');}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);}},failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});}});Ext.define('designer.properties.GridEditor',{extend:'designer.properties.Field',columnName:null,initComponent:function(){this.tbar.push({text:desLang.removeEditor,scope:this,handler:this.removeEditor,iconCls:'deleteIcon'});this.setExtraParams({column:this.columnName});this.callParent(arguments);},removeEditor:function() {Ext.Ajax.request({url:this.controllerUrl+'remove',method:'post',scope:this,params:this.extraParams,success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){this.dataGrid.setSource({});this.fireEvent('editorRemoved',response);}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);}},failure:function(){Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});this.fireEvent('editorRemoved');}});Ext.define('designer.properties.FilterComponent',{extend:'designer.properties.Panel',layout:'accordion',fieldProperties:null,initComponent:function() -{this.mainConfigTitle=desLang.properties;this.fieldsStore=Ext.create('Ext.data.Store',{model:'app.comboStringModel',proxy:{type:'ajax',url:this.controllerUrl+'storefields',reader:{type:'json',rootProperty:'data',idProperty:'id'},extraParams:{object:this.objectName},simpleSortMode:true},remoteSort:false,autoLoad:true,sorters:[{property:'id',direction:'ASC'}]});this.sourceConfig=Ext.apply({'storeField':{editor:Ext.create('Ext.form.ComboBox',{selectOnFocus:true,editable:true,triggerAction:'all',anchor:'100%',queryMode:'remote',store:this.fieldsStore,valueField:'id',displayField:'id',allowBlank:true,forceSelection:false})},'type':{editor:Ext.create('Ext.form.field.ComboBox',{typeAhead:true,triggerAction:'all',selectOnTab:true,labelWidth:80,forceSelection:true,queryMode:'local',store:[['Component',desLang.component],['Field',desLang.field]]})}});var me=this;this.callParent();this.fieldProperties=Ext.create('designer.properties.Field',{title:desLang.advancedOptions,controllerUrl:app.createUrl([designer.controllerUrl,'filter','']),objectName:this.objectName,application:me});this.fieldProperties.on('dataSaved',function(){this.fireEvent('dataSaved');},this);this.fieldProperties.on('objectsUpdated',function(){this.fireEvent('objectsUpdated');},this);this.add(this.fieldProperties);}});Ext.define('designer.properties.Search',{extend:'designer.properties.Field',initComponent:function() +{this.eventsControllerUrl=app.createUrl([designer.controllerUrl,'filterEvents','']);this.mainConfigTitle=desLang.properties;this.fieldsStore=Ext.create('Ext.data.Store',{model:'app.comboStringModel',proxy:{type:'ajax',url:this.controllerUrl+'storefields',reader:{type:'json',rootProperty:'data',idProperty:'id'},extraParams:{object:this.objectName},simpleSortMode:true},remoteSort:false,autoLoad:true,sorters:[{property:'id',direction:'ASC'}]});this.sourceConfig=Ext.apply({'storeField':{editor:Ext.create('Ext.form.ComboBox',{selectOnFocus:true,editable:true,triggerAction:'all',anchor:'100%',queryMode:'remote',store:this.fieldsStore,valueField:'id',displayField:'id',allowBlank:true,forceSelection:false})},'type':{editor:Ext.create('Ext.form.field.ComboBox',{typeAhead:true,triggerAction:'all',selectOnTab:true,labelWidth:80,forceSelection:true,queryMode:'local',store:[['Component',desLang.component],['Field',desLang.field]]})}});var me=this;this.callParent();this.fieldProperties=Ext.create('designer.properties.Field',{title:desLang.advancedOptions,controllerUrl:app.createUrl([designer.controllerUrl,'filter','']),objectName:this.objectName,application:me,showEvents:false});this.fieldProperties.on('dataSaved',function(){this.fireEvent('dataSaved');},this);this.fieldProperties.on('objectsUpdated',function(){this.fireEvent('objectsUpdated');},this);this.add(this.fieldProperties);}});Ext.define('designer.properties.Search',{extend:'designer.properties.Field',initComponent:function() {var me=this;this.sourceConfig=Ext.apply({'fieldNames':{editor:Ext.create('Ext.form.field.Text',{listeners:{'focus':{fn:me.namesEdior,scope:me}}}),renderer:function(v){return'...';}}},this.sourceConfig);this.callParent();},namesEdior:function(){var storeProperty=this.dataGrid.getSource().store;var fieldsList=this.dataGrid.getSource().fieldNames;if(fieldsList.length){fieldsList=Ext.JSON.decode(fieldsList);}else{fieldsList=[];} if(!storeProperty.length){Ext.Msg.alert(appLang.MESSAGE,desLang.selectDataStore);return;} Ext.create('designer.properties.SearchFieldsWindow',{fieldsStore:storeProperty,initData:fieldsList,listeners:{dataChanged:{fn:function(data){this.dataGrid.setProperty('fieldNames',data);this.fireEvent('dataChanged');},scope:this}}}).show();}});Ext.define('designer.properties.SearchFieldsWindow',{extend:'Ext.Window',width:200,height:300,title:'fieldNames',initData:null,dataGrid:null,dataStore:null,fieldsStore:null,closeAction:'destroy',resizable:false,layout:'fit',storeName:'',initComponent:function(){if(Ext.isEmpty(this.initData)){this.initData=[];}else{var data=[];Ext.each(this.initData,function(item){data.push([item]);},this);this.initData=data;} this.dataStore=Ext.create('Ext.data.ArrayStore',{fields:['id'],data:this.initData}),this.fieldStore=Ext.create('Ext.data.Store',{proxy:{type:'ajax',url:app.createUrl([designer.controllerUrl,'store','listfields']),reader:{type:'json',idProperty:'name',rootProperty:'data'},extraParams:{object:this.fieldsStore},autoLoad:true},fields:[{name:'name',type:'string'},{name:'type',type:'string'}],autoLoad:true});this.tbar=[{tooltip:desLang.add,iconCls:'plusIcon',scope:this,handler:this.addRecord}];this.cellEditing=Ext.create('Ext.grid.plugin.CellEditing',{clicksToEdit:1});this.dataGrid=Ext.create('Ext.grid.Panel',{store:this.dataStore,columnLines:true,hideHeaders:true,columns:[{dataIndex:'id',editable:true,flex:1,editor:{xtype:'combobox',typeAhead:true,triggerAction:'all',selectOnTab:true,forceSelection:true,store:this.fieldStore,displayField:'name',valueField:'name',allowBlank:false,queryMode:'local'}},{xtype:'actioncolumn',width:25,align:'center',sortable:false,menuDisabled:true,items:[{iconCls:'deleteIcon',tooltip:desLang.remove,handler:function(grid,row,col){var store=grid.getStore();store.remove(store.getAt(row));}}]}],plugins:[this.cellEditing]});this.items=[this.dataGrid];this.buttons=[{text:desLang.save,handler:this.sendData,scope:this},{text:desLang.close,handler:this.close,scope:this}];this.callParent();},sendData:function() {var data=[];this.dataStore.each(function(record){var name=record.get('id');if(name.length){data.push(record.get('id'));}},this);data=Ext.JSON.encode(data);this.fireEvent('dataChanged',data);this.close();},addRecord:function(){var count=this.dataStore.getCount();var r=[''];this.dataStore.insert(count,r);this.cellEditing.startEditByPosition({row:count,column:0});}});Ext.define('designer.properties.MediaItem',{extend:'designer.properties.Field',initComponent:function() -{this.sourceConfig=Ext.apply({'resourceType':{editor:Ext.create('Ext.form.ComboBox',{selectOnFocus:true,editable:true,triggerAction:'all',anchor:'100%',queryMode:'local',store:app.medialib.typesStore,valueField:'id',displayField:'title',allowBlank:true})}});this.callParent();}});Ext.ns('designer.model');Ext.define('designer.model.fieldsModel',{extend:'Ext.data.Model',fields:[{name:'name',type:'string'},{name:'type',type:'string'}],idProperty:'name'});Ext.define('designer.model.associationsModel',{extend:'Ext.data.Model',fields:[{name:'field',type:'string'},{name:'model',type:'string'},{name:'type',type:'string'}],idProperty:'field'});Ext.define('designer.model.validationsModel',{extend:'Ext.data.Model',fields:[{name:'field',type:'string'},{name:'type',type:'string'}],idProperty:'field'});Ext.define('designer.model.configWindow',{extend:'Ext.Window',width:600,height:600,layout:'fit',tabPanel:null,activeTab:0,modal:true,title:desLang.modelConfig,objectName:null,controllerUrl:null,fieldsGrid:null,fieldsStore:null,initFields:[],initAssociations:[],initValidators:[],fieldsCellEditing:null,initFieldsEditor:function(){var me=this;this.fieldsStore=Ext.create('Ext.data.Store',{autoDestroy:true,model:'designer.model.fieldsModel',autoLoad:true,proxy:{type:'ajax',url:app.createUrl([designer.controllerUrl,'model','listfields']),extraParams:{object:this.objectName},reader:{idProperty:"name",rootProperty:"data",type:"json"}}});this.fieldsProperties=Ext.create('designer.properties.dataField',{title:'',controllerUrl:app.createUrl([designer.controllerUrl,'datafield','']),objectName:this.objectName,autoLoadData:false,width:380,autoLoad:false,title:desLang.properties,layout:'fit',region:'east',showEvents:false,split:true,width:250});this.fieldsCellEditing=Ext.create('Ext.grid.plugin.CellEditing',{clicksToEdit:1});this.fieldsGrid=Ext.create('Ext.grid.Panel',{region:'center',store:this.fieldsStore,columnLines:true,columns:[{text:desLang.field,dataIndex:'name',flex:1,editor:{xtype:'textfield',vtype:'alphanum',allowBlank:false}},{text:desLang.type,dataIndex:'type',flex:1,editor:{xtype:'combobox',typeAhead:true,selectOnFocus:true,editable:true,triggerAction:'all',anchor:'100%',queryMode:'local',forceSelection:true,displayField:'id',valueField:'id',store:Ext.create('Ext.data.ArrayStore',{fields:['id'],data:this.fieldsProperties.fieldtypes})}},{xtype:'actioncolumn',width:25,sortable:false,menuDisabled:true,align:'center',items:[{iconCls:'deleteIcon',tooltip:desLang.remove,scope:me,handler:function(grid,row,col){var store=grid.getStore();me.removeField(store.getAt(row));}}]}],plugins:[this.fieldsCellEditing],tbar:[{iconCls:'importOrmIcon',tooltip:desLang.importOrm,scope:this,handler:this.importFromOrm},{iconCls:'importDbIcon',tooltip:desLang.importDb,scope:this,handler:this.importFromDb},{tooltip:desLang.add,iconCls:'plusIcon',scope:this,handler:this.addField}],listeners:{scope:this,edit:function(editor,o){this.fieldsProperties.dataGrid.setProperty(o.field,o.value);this.fieldsStore.commitChanges();if(o.field==='name'){this.fieldsProperties.setExtraParams({'id':o.value});}}}});this.fieldsGrid.getSelectionModel().on('selectionchange',function(sm,data,opts){this.fieldsCellEditing.cancelEdit();if(!sm.hasSelection()){this.fieldsProperties.resetProperties();this.fieldsProperties.refreshEvents();return;} +{this.sourceConfig=Ext.apply({'resourceType':{editor:Ext.create('Ext.form.ComboBox',{selectOnFocus:true,editable:true,triggerAction:'all',anchor:'100%',queryMode:'local',store:app.medialib.typesStore,valueField:'id',displayField:'title',allowBlank:true})}});this.callParent();}});Ext.ns('designer.model');Ext.define('designer.model.fieldsModel',{extend:'Ext.data.Model',fields:[{name:'name',type:'string'},{name:'type',type:'string'}],idProperty:'name'});Ext.define('designer.model.associationsModel',{extend:'Ext.data.Model',fields:[{name:'field',type:'string'},{name:'model',type:'string'},{name:'type',type:'string'}],idProperty:'field'});Ext.define('designer.model.validationsModel',{extend:'Ext.data.Model',fields:[{name:'field',type:'string'},{name:'type',type:'string'}],idProperty:'field'});Ext.define('designer.model.configWindow',{extend:'Ext.Window',width:600,height:600,layout:'fit',tabPanel:null,activeTab:0,modal:true,title:desLang.modelConfig,objectName:null,controllerUrl:null,fieldsGrid:null,fieldsStore:null,initFields:[],initAssociations:[],initValidators:[],fieldsCellEditing:null,initFieldsEditor:function(){var me=this;this.fieldsStore=Ext.create('Ext.data.Store',{autoDestroy:true,model:'designer.model.fieldsModel',autoLoad:true,proxy:{type:'ajax',url:app.createUrl([designer.controllerUrl,'model','listfields']),extraParams:{object:this.objectName},reader:{idProperty:"name",rootProperty:"data",type:"json"}}});this.fieldsProperties=Ext.create('designer.properties.dataField',{controllerUrl:app.createUrl([designer.controllerUrl,'datafield','']),objectName:this.objectName,autoLoadData:false,autoLoad:false,title:desLang.properties,layout:'fit',region:'east',showEvents:false,split:true,width:250});this.fieldsCellEditing=Ext.create('Ext.grid.plugin.CellEditing',{clicksToEdit:1});this.fieldsGrid=Ext.create('Ext.grid.Panel',{region:'center',store:this.fieldsStore,columnLines:true,columns:[{text:desLang.field,dataIndex:'name',flex:1,editor:{xtype:'textfield',vtype:'alphanum',allowBlank:false}},{text:desLang.type,dataIndex:'type',flex:1,editor:{xtype:'combobox',typeAhead:true,selectOnFocus:true,editable:true,triggerAction:'all',anchor:'100%',queryMode:'local',forceSelection:true,displayField:'id',valueField:'id',store:Ext.create('Ext.data.ArrayStore',{fields:['id'],data:this.fieldsProperties.fieldtypes})}},{xtype:'actioncolumn',width:25,sortable:false,menuDisabled:true,align:'center',items:[{iconCls:'deleteIcon',tooltip:desLang.remove,scope:me,handler:function(grid,row,col){var store=grid.getStore();me.removeField(store.getAt(row));}}]}],plugins:[this.fieldsCellEditing],tbar:[{iconCls:'importOrmIcon',tooltip:desLang.importOrm,scope:this,handler:this.importFromOrm},{iconCls:'importDbIcon',tooltip:desLang.importDb,scope:this,handler:this.importFromDb},{tooltip:desLang.add,iconCls:'plusIcon',scope:this,handler:this.addField}],listeners:{scope:this,edit:function(editor,o){this.fieldsProperties.dataGrid.setProperty(o.field,o.value);this.fieldsStore.commitChanges();if(o.field==='name'){this.fieldsProperties.setExtraParams({'id':o.value});}}}});this.fieldsGrid.getSelectionModel().on('selectionchange',function(sm,data,opts){this.fieldsCellEditing.cancelEdit();if(!sm.hasSelection()){this.fieldsProperties.resetProperties();this.fieldsProperties.refreshEvents();return;} this.fieldsProperties.setExtraParams({'id':sm.getSelection()[0].get('name')});this.fieldsProperties.loadProperties();},this);this.fieldsProperties.dataGrid.on('propertychange',function(source,recordId,value){if(recordId==='name'||recordId==='type'){var sm=this.fieldsGrid.getSelectionModel();if(sm.hasSelection()){var record=sm.getLastSelected();record.beginEdit();record.set(recordId,value);record.endEdit();record.commit();this.fireEvent('dataChanged');}}},this);this.fieldsEditor=Ext.create('Ext.Panel',{title:desLang.fields,layout:'border',frame:false,items:[this.fieldsGrid,this.fieldsProperties]});return this.fieldsEditor;},initComponent:function(){var me=this;this.initFieldsEditor();this.associationsGrid=Ext.create('Ext.grid.Panel',{title:desLang.associations,store:Ext.create('Ext.data.Store',{autoDestroy:true,model:'designer.model.associationsModel',autoLoad:false,data:this.initAssociations}),columns:[{text:desLang.field,dataIndex:'field',flex:1,editor:{xtype:'combobox',typeAhead:true,triggerAction:'all',queryMode:'local',selectOnTab:true,valueField:'name',displayField:'name',forceSelection:true,store:me.fieldsStore}},{text:desLang.type,dataIndex:'type',flex:1,editor:{xtype:'combobox',typeAhead:true,triggerAction:'all',selectOnTab:true,forceSelection:true,store:[['hasMany','Has Many'],['belongsTo','Belongs To']]}},{text:desLang.model,dataIndex:'model',flex:1,editor:{xtype:'combobox',typeAhead:true,triggerAction:'all',queryMode:'local',selectOnTab:true,valueField:'id',displayField:'id',forceSelection:true,store:app.designer.getModelsStore()}},{xtype:'actioncolumn',width:25,align:'center',sortable:false,menuDisabled:true,items:[{iconCls:'deleteIcon',tooltip:desLang.remove,handler:function(grid,row,col){var store=grid.getStore();store.remove(store.getAt(row));}}]}],plugins:[Ext.create('Ext.grid.plugin.CellEditing',{clicksToEdit:1})],tbar:[{tooltip:desLang.add,iconCls:'plusIcon',scope:this,handler:this.addAssociation}]});this.validationsGrid=Ext.create('Ext.grid.Panel',{title:desLang.validators,store:Ext.create('Ext.data.Store',{autoDestroy:true,model:'designer.model.validationsModel',autoLoad:false,data:this.initValidators}),columns:[{text:desLang.field,dataIndex:'field',flex:1,editor:{xtype:'combobox',typeAhead:true,triggerAction:'all',queryMode:'local',selectOnTab:true,valueField:'name',displayField:'name',forceSelection:true,store:this.fieldsStore}},{text:desLang.type,dataIndex:'type',flex:1,editor:{xtype:'combobox',typeAhead:true,triggerAction:'all',selectOnTab:true,forceSelection:true,store:[['alpha','alpha'],['alphanum','alphanum'],['email','email'],['url','url']]}},{xtype:'actioncolumn',width:25,align:'center',sortable:false,menuDisabled:true,items:[{iconCls:'deleteIcon',tooltip:desLang.remove,handler:function(grid,row,col){var store=grid.getStore();store.remove(store.getAt(row));}}]}],plugins:[Ext.create('Ext.grid.plugin.CellEditing',{clicksToEdit:1})],tbar:[{tooltip:desLang.add,iconCls:'plusIcon',scope:this,handler:this.addValidation}]});this.tabPanel=Ext.create('Ext.tab.Panel',{activeTab:this.activeTab,layout:'fit',defaults:{layout:'fit',scrollable:true},items:[this.fieldsEditor,this.associationsGrid,this.validationsGrid]});this.buttons=[{text:desLang.save,handler:this.saveData,scope:this},{text:desLang.close,scope:this,handler:this.close}];this.items=[this.tabPanel];this.callParent(arguments);},importFromOrm:function(){var win=Ext.create('designer.ormSelectorWindow',{});win.on('select',function(objectName,fields){this.setLoading(true);Ext.Ajax.request({url:app.createUrl([designer.controllerUrl,'model',''])+'importormfields/',method:'post',scope:this,params:{object:this.objectName,objectName:objectName,'fields[]':fields},success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){this.fieldsStore.load();}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);} this.setLoading(false);},failure:function(){this.setLoading(false);Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});},this);win.show();},importFromDb:function(){var win=Ext.create('designer.importDBWindow',{title:desLang.importDb});win.on('select',function(fields,connectionId,table,contype){this.setLoading(true);Ext.Ajax.request({url:app.createUrl([designer.controllerUrl,'model',''])+'importdbfields/',method:'post',scope:this,params:{object:this.objectName,'fields[]':fields,connectionId:connectionId,table:table,type:contype},success:function(response,request){response=Ext.JSON.decode(response.responseText);if(response.success){this.fieldsStore.load();}else{Ext.Msg.alert(appLang.MESSAGE,response.msg);} this.setLoading(false);},failure:function(){this.setLoading(false);Ext.Msg.alert(appLang.MESSAGE,appLang.MSG_LOST_CONNECTION);}});},this);win.show();},fieldsHasDirtyRecords:function(){var has=false;this.fieldsStore.each(function(record){if(record.dirty||record.phantom){has=true;}},this);return has;},addField:function(){var me=this;Ext.MessageBox.prompt(appLang.MESSAGE,desLang.enterFieldName,function(btn,text){if(btn!='ok'){return;} diff --git a/www/js/app/system/ImportPanel.js b/www/js/app/system/ImportPanel.js index 145a521e..8a2cae94 100644 --- a/www/js/app/system/ImportPanel.js +++ b/www/js/app/system/ImportPanel.js @@ -74,7 +74,7 @@ Ext.define('app.import.Panel',{ * Additional import form fields * @property {Array} */ - importFormFields:[], + importFormFields:null, /** * @property Ext.form.FieldSet, */ @@ -171,7 +171,7 @@ Ext.define('app.import.Panel',{ width:10 }, { - value:this.lang.click_column, + value: '
'+ this.lang.hint + ':
' + this.lang.click_column+'
', xtype:'displayfield', name:'importlabel', hidden:true @@ -391,7 +391,7 @@ Ext.define('app.import.Panel',{ dataColumns.push({ header: header, dataIndex: 'col'+i, - id:'col'+i, + itemId:'col'+i, sortable: false, menuDisabled: true, width:140, @@ -660,8 +660,7 @@ Ext.define('app.import.Panel',{ Ext.each(this.expectedColumns , function(record){ params['columns['+record.id+']'] = record.columnIndex; if(record.columnIndex == -1){ - if(record.required || this.visibleGroup == record.group){ - + if(record.required || (!Ext.isEmpty(this.visibleGroup) && this.visibleGroup == record.group)){ error = true; } } diff --git a/www/js/app/system/ObjectLink.js b/www/js/app/system/ObjectLink.js index 587ab040..e4316f5c 100644 --- a/www/js/app/system/ObjectLink.js +++ b/www/js/app/system/ObjectLink.js @@ -36,6 +36,8 @@ Ext.define('app.objectLink.Field',{ this.callParent(arguments); }, + updateObjectTitle:true, + initComponent:function(){ var me = this; @@ -43,38 +45,33 @@ Ext.define('app.objectLink.Field',{ anchor:"100%", readOnly :true, name:this.name, - listeners:{ - focus:{ - fn:this.showSelectionWindow, - scope:this - }, - change:{ - fn:this.getObjectTitle, - scope:this - } - } + allowBlank:this.allowBlank }); + this.dataField.on('change', me.getObjectTitle, me); + this.dataField.on('focus', me.showSelectionWindow, me); + this.dataFieldLabel = Ext.create('Ext.form.field.Text',{ anchor:"100%", flex:1, value:"...", editable:false, + submitValue:false, // cls:'d_objectLink_input', triggers: { select: { cls: 'x-form-search-trigger', handler:me.showSelectionWindow, tooltip:appLang.SELECT, - scope:this + scope:me }, clear: { cls: 'x-form-clear-trigger', tooltip:appLang.RESET, handler:function(){ - me.setValue(""); + me.setValue(''); }, - scope:this + scope:me } } }); @@ -92,6 +89,12 @@ Ext.define('app.objectLink.Field',{ this.updateViewState(); }, + isValid:function(){ + return this.dataField.isValid(); + }, + markInvalid:function(){ + this.dataFieldLabel.markInvalid(); + }, showSelectionWindow:function(){ if(this.readOnly || this.disabled){ @@ -107,15 +110,18 @@ Ext.define('app.objectLink.Field',{ title:this.fieldLabel, extraParams:this.extraParams }); + win.on('itemSelected',function(record){ - this.setValue(record.get('id')); + this.setRawData(record.get('id'),record.get('title')); this.fireEvent('completeEdit'); win.close(); },this); + win.show(); app.checkSize(win); }, setValue:function(value){ + this.updateObjectTitle = true; this.dataField.setValue(value); this.fireEvent('change' , this); }, @@ -123,18 +129,31 @@ Ext.define('app.objectLink.Field',{ return this.dataField.getValue(); }, reset:function(){ + this.updateObjectTitle = true; this.dataField.reset(); + this.dataFieldLabel.reset(); this.fireEvent('change' , this); }, - isValid:function(){ - return true; + setRawData:function(id,title){ + this.dataField.setValue(id); + this.dataFieldLabel.setValue(title); + this.updateObjectTitle = false; + this.fireEvent('change' , this); }, - getObjectTitle:function(){ + setObjectTitle:function(title){ + this.dataFieldLabel.setValue(title); + this.updateLayout(); + }, + getObjectTitle:function() { var me = this; var curValue = me.getValue(); if(curValue == "" || curValue == 0){ - me.dataFieldLabel.setValue(''); + me.dataFieldLabel.setValue('...'); + return; + } + + if(!this.updateObjectTitle){ return; } diff --git a/www/js/app/system/Page.js b/www/js/app/system/Page.js index 8c08b2ee..abd1e971 100644 --- a/www/js/app/system/Page.js +++ b/www/js/app/system/Page.js @@ -560,6 +560,7 @@ Ext.define('app.crud.page.Panel',{ var index = this.dataStore.getById(parseInt(rec.get('id'))); if(index!=undefined){ this.dataGrid.getSelectionModel().select(index , false , false); + this.dataGrid.getView().focusRow(index); } },this); @@ -574,6 +575,7 @@ Ext.define('app.crud.page.Panel',{ var node = this.dataTree.getStore().getNodeById(''+rec.get('id')); if(node!=null){ this.dataTree.getSelectionModel().select(node , false , true); + this.dataTree.getView().focusRow(rec); } },this); diff --git a/www/js/app/system/common.js b/www/js/app/system/common.js index ad0171b0..ba12118c 100644 --- a/www/js/app/system/common.js +++ b/www/js/app/system/common.js @@ -439,7 +439,13 @@ Ext.apply(Ext.form.field.VTypes, { } return true; }, - valuematchText: appLang.VALUENOTMATCH + valuematchText: appLang.VALUENOTMATCH, + pagecode:function(val, field){ + var exp = /^[a-zA-Z0-9_-]+$/; + return exp.test(val); + }, + pagecodeText:appLang.URL_PAGECODE_MATCH, + pagecodeMask: /[a-z0-9_-]/i }); /** diff --git a/www/js/app/system/designer/application.js b/www/js/app/system/designer/application.js index 8dddedf6..35ed35a6 100644 --- a/www/js/app/system/designer/application.js +++ b/www/js/app/system/designer/application.js @@ -544,6 +544,11 @@ Ext.define('designer.application',{ iconCls:'comboboxFieldIcon', showType:'loaded', oClass:'Form_Field_Combobox' + },{ + text:'Tag Field', + iconCls:'tagIcon', + showType:'loaded', + oClass:'Form_Field_Tag' } ] }) diff --git a/www/js/app/system/designer/eventsEditor.js b/www/js/app/system/designer/eventsEditor.js index 2325131e..d7f94554 100644 --- a/www/js/app/system/designer/eventsEditor.js +++ b/www/js/app/system/designer/eventsEditor.js @@ -183,7 +183,7 @@ Ext.define('designer.eventsEditor',{ Ext.define('designer.eventsEditorWindow',{ extend:'Ext.Window', modal:true, - width:500, + width:800, height:600, layout:{ type: 'vbox', @@ -283,7 +283,12 @@ Ext.define('designer.eventsEditorWindow',{ //this.items = [this.centerPanel]; this.callParent(); - this.on('show',this.loadCode,this); + this.on('show', function(){ + this.loadCode(); + app.checkSize(this); + Ext.WindowMgr.register(this); + Ext.WindowMgr.bringToFront(this); + }, this); }, loadCode:function(){ diff --git a/www/js/app/system/designer/grid.js b/www/js/app/system/designer/grid.js index 86572282..2a8908a4 100644 --- a/www/js/app/system/designer/grid.js +++ b/www/js/app/system/designer/grid.js @@ -29,7 +29,7 @@ Ext.define('designer.grid.exportFieldsWin',{ model:'designer.model.fieldsModel', proxy: { type: 'ajax', - url:app.createUrl([designer.controllerUrl ,'store','']) + 'listfields', + url:app.createUrl([designer.controllerUrl ,'store','']) + 'allfields', reader: { type: 'json', rootProperty: 'data', diff --git a/www/js/app/system/designer/grid/column.js b/www/js/app/system/designer/grid/column.js index 64d79d02..35b5569d 100644 --- a/www/js/app/system/designer/grid/column.js +++ b/www/js/app/system/designer/grid/column.js @@ -215,7 +215,7 @@ Ext.define('designer.grid.column.Window',{ model:'designer.model.fieldsModel', proxy: { type: 'ajax', - url:app.createUrl([designer.controllerUrl ,'store','']) + 'listfields', + url:app.createUrl([designer.controllerUrl ,'store','']) + 'allfields', reader: { type: 'json', rootProperty: 'data' diff --git a/www/js/app/system/designer/methodEditor.js b/www/js/app/system/designer/methodEditor.js index da96053f..910709d8 100644 --- a/www/js/app/system/designer/methodEditor.js +++ b/www/js/app/system/designer/methodEditor.js @@ -192,7 +192,7 @@ Ext.define('designer.methodsEditor',{ Ext.define('designer.methodEditorWindow',{ extend:'Ext.Window', modal:false, - width:500, + width:800, height:600, y:20, layout:{ @@ -303,7 +303,13 @@ Ext.define('designer.methodEditorWindow',{ this.items = [this.dataForm ]; this.callParent(); - this.on('show',this.loadMethodData,this); + + this.on('show', function(){ + this.loadMethodData(); + app.checkSize(this); + Ext.WindowMgr.register(this); + Ext.WindowMgr.bringToFront(this); + }, this); }, /** * Request method data diff --git a/www/js/app/system/designer/model.js b/www/js/app/system/designer/model.js index fbb52861..4a1f7d59 100644 --- a/www/js/app/system/designer/model.js +++ b/www/js/app/system/designer/model.js @@ -82,11 +82,9 @@ Ext.define('designer.model.configWindow',{ }); this.fieldsProperties = Ext.create('designer.properties.dataField',{ - title:'', controllerUrl: app.createUrl([designer.controllerUrl ,'datafield','']), objectName:this.objectName, autoLoadData:false, - width:380, autoLoad:false, title:desLang.properties, layout:'fit', diff --git a/www/js/app/system/designer/ormSelectorWindow.js b/www/js/app/system/designer/ormSelectorWindow.js index f4979b03..53ab04e0 100644 --- a/www/js/app/system/designer/ormSelectorWindow.js +++ b/www/js/app/system/designer/ormSelectorWindow.js @@ -7,7 +7,7 @@ Ext.define('designer.ormSelectorWindow',{ extend:'Ext.Window', title:desLang.importOrm, - width:600, + width:700, height:500, objectsGrid:null, fieldsGrid:null, @@ -15,31 +15,41 @@ Ext.define('designer.ormSelectorWindow',{ initComponent:function(){ + var store = Ext.create('Ext.data.Store',{ + fields:[ + {name:'name' , type:'string'}, + {name:'title' , type:'string'} + ], + proxy:{ + url:app.createUrl([designer.controllerUrl ,'orm','list','']), + type:'ajax', + reader:{ + type:'json', + idProperty:'name', + rootProperty:'data' + } + }, + autoLoad:true, + sorters: [{ + property : 'name', + direction: 'ASC' + }] + }); + this.objectsGrid = Ext.create('Ext.grid.Panel',{ split:true, title:desLang.objects, region:'center', columnLines:true, - store:Ext.create('Ext.data.Store',{ - fields:[ - {name:'name' , type:'string'}, - {name:'title' , type:'string'} - ], - proxy:{ - url:app.createUrl([designer.controllerUrl ,'orm','list','']), - type:'ajax', - reader:{ - type:'json', - idProperty:'name', - rootProperty:'data' - } - }, - autoLoad:true, - sorters: [{ - property : 'name', - direction: 'ASC' - }] - }), + tbar:[ + '->', + Ext.create('SearchPanel',{ + fieldNames:['name','title'], + store:store, + local:true + }) + ], + store:store, columns:[ { text:desLang.name, @@ -125,7 +135,12 @@ Ext.define('designer.ormSelectorWindow',{ ]; this.items = [this.objectsGrid , this.fieldsGrid]; - this.callParent(arguments); + + this.callParent(); + + this.on('show',function(){ + app.checkSize(this); + },this); }, onSelect:function(){ var oSm = this.objectsGrid.getSelectionModel(); diff --git a/www/js/app/system/designer/properties.js b/www/js/app/system/designer/properties.js index a3ad1cba..a645dcfd 100644 --- a/www/js/app/system/designer/properties.js +++ b/www/js/app/system/designer/properties.js @@ -208,6 +208,19 @@ Ext.define('designer.properties.Panel', { store: storesStore }) }, + // 'mapping':{ + // editor:Ext.create('Ext.form.field.ComboBox',{ + // typeAhead: true, + // triggerAction: 'all', + // selectOnTab: true, + // labelWidth:80, + // forceSelection:false, + // queryMode:'local', + // displayField:'title', + // valueField:'title', + // store:app.designer.getModelsStore() + // }) + // }, 'menu': { editor: Ext.create('Ext.form.field.ComboBox', { typeAhead: true, diff --git a/www/js/app/system/designer/properties/filterComponent.js b/www/js/app/system/designer/properties/filterComponent.js index d3801036..683d9bf8 100644 --- a/www/js/app/system/designer/properties/filterComponent.js +++ b/www/js/app/system/designer/properties/filterComponent.js @@ -7,6 +7,8 @@ Ext.define('designer.properties.FilterComponent',{ fieldProperties: null, initComponent:function() { + this.eventsControllerUrl = app.createUrl([designer.controllerUrl ,'filterEvents','']); + this.mainConfigTitle = desLang.properties; this.fieldsStore = Ext.create('Ext.data.Store',{ @@ -77,7 +79,8 @@ Ext.define('designer.properties.FilterComponent',{ title:desLang.advancedOptions, controllerUrl:app.createUrl([designer.controllerUrl ,'filter','']), objectName:this.objectName, - application:me + application:me, + showEvents:false }); this.fieldProperties.on('dataSaved',function(){ @@ -89,6 +92,5 @@ Ext.define('designer.properties.FilterComponent',{ },this); this.add(this.fieldProperties); - } }); diff --git a/www/js/app/system/designer/style.css b/www/js/app/system/designer/style.css index 520c3589..a0351944 100644 --- a/www/js/app/system/designer/style.css +++ b/www/js/app/system/designer/style.css @@ -252,6 +252,9 @@ .pagingIcon{ background-image:url(../../../../i/system/designer/pagination.png) !important; } +.tagIcon{ + background-image: url(../../../../i/system/designer/tag.png) !important; +} .urlTrigger{ width:25px !important;