summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel <darthdaniel85@gmail.com>2013-11-22 15:25:30 -0500
committerDaniel <darthdaniel85@gmail.com>2013-11-22 15:25:30 -0500
commitab6effd64caefa732ef0994d6c3048f5cd474bf6 (patch)
tree73f4e568295f4d7625fc16af9ce03c58bbbaab2a
parent85ca63b0896be3d12a098b44b5ec0c65a5b76a6c (diff)
WSAT beta release.
-rw-r--r--framework/Wsat/TWsatARGenerator.php368
-rw-r--r--framework/Wsat/TWsatService.php123
-rw-r--r--framework/Wsat/pages/TWsatGenerateAR.page20
-rw-r--r--framework/Wsat/pages/TWsatGenerateAR.php80
-rw-r--r--framework/Wsat/pages/TWsatLogin.page7
-rw-r--r--framework/Wsat/pages/TWsatLogin.php59
-rw-r--r--framework/Wsat/themes/PradoSoft/main.css282
7 files changed, 541 insertions, 398 deletions
diff --git a/framework/Wsat/TWsatARGenerator.php b/framework/Wsat/TWsatARGenerator.php
index 7b39fce1..433e1640 100644
--- a/framework/Wsat/TWsatARGenerator.php
+++ b/framework/Wsat/TWsatARGenerator.php
@@ -1,136 +1,232 @@
-<?php
-
-/**
- * Description of TWsatARGenerator
- *
- * @author Daniel
- */
-class TWsatARGenerator {
-
- /**
- * @return TActiveRecordManager static instance of record manager.
- */
- private $_ar_manager;
-
- /**
- * Output folder (by namespace) where AR classes will be generated.
- */
- private $_opnamespace;
-
- function __construct($_opnamespace = "Application.App_Data.AR_Classes") {
- $this->_ar_manager = TActiveRecordManager::getInstance();
- $this->_opnamespace = $_opnamespace;
- }
-
- // <editor-fold defaultstate="collapsed" desc="Main APIs">
- public function generate($tableName, $clasName = '') {
- $conn = $this->_ar_manager->getDbConnection();
- $gateway = $this->_ar_manager->getRecordGateway();
- $tableInfo = $gateway->getTableInfo($conn, $tableName);
-
- if (count($tableInfo->getColumns()) === 0) {
- throw new TIOException("Unable to find table or view $tableName in " . $conn->getConnectionString() . ".");
- } else {
- $properties = array();
- foreach ($tableInfo->getColumns() as $field => $column)
- $properties[] = $this->generateProperty($field, $column);
- }
-
- $clasName = empty($clasName) ? $this->_getClassName($tableName) : $clasName;
- $class = $this->generateClass($properties, $tableName, $clasName);
- $op_file = Prado::getPathOfNamespace($this->_opnamespace);
- if (!is_dir($op_file)) {
- mkdir($op_file, 0777, true);
- }
-
- $output = $op_file . DIRECTORY_SEPARATOR . $clasName . ".php";
- file_put_contents($output, $class);
- }
-
- public function generateAll() {
- foreach ($this->_getAllTableNames() as $tableName) {
- $this->generate($tableName);
- }
- }
-
-// </editor-fold>
-//-----------------------------------------------------------------------------
- // <editor-fold defaultstate="collapsed" desc="Common Methods">
- private function getDbConnection() {
- $con = $this->_ar_manager->getDbConnection();
- $con->Active = true;
- return $con;
- }
-
- private function _getAllTableNames() {
- $con = $this->getDbConnection();
- $command = $con->createCommand("Show Tables");
- $dataReader = $command->query();
- $dataReader->bindColumn(1, $table);
- $tables = array();
- while ($dataReader->read()) {
- $tables[] = $table;
- }
- $con->setActive(false);
- return $tables;
- }
-
- private function _getClassName($tableName) {
- return ucfirst($tableName);
- }
-
- public function renderAllTablesInformation() {
- $conn = $this->_ar_manager->getDbConnection();
- $gateway = $this->_ar_manager->getRecordGateway();
-
- foreach ($this->_getAllTableNames() as $table_name) {
- echo $table_name . "<br>";
-
- $tableInfo = $gateway->getTableInfo($conn, $table_name);
- echo "Table info:" . "<br>";
- echo "<pre>";
- var_dump($tableInfo);
- echo "</pre>";
- }
- }
-
-//-----------------------------------------------------------------------------
-
- protected function generateProperty($field, $column) {
- $prop = '';
- $name = '$' . $field;
-
- /* TODO use in version 2.0 */
- // $type = $column->getPHPType();
-
- $prop .= "\tpublic $name;";
- return $prop;
- }
-
- protected function generateClass($properties, $tablename, $class) {
- $props = implode("\n", $properties);
- $date = date('Y-m-d h:i:s');
- return <<<EOD
-<?php
-/**
- * Auto generated by prado-cli.php on $date.
- */
-class $class extends TActiveRecord
-{
- const TABLE='$tablename';
-
-$props
-
- public static function finder(\$className=__CLASS__)
- {
- return parent::finder(\$className);
- }
-}
-?>
-EOD;
- }
-
-// </editor-fold>
-}
-
-?>
+<?php
+
+/**
+ * Description of TWsatARGenerator
+ *
+ * @author Daniel
+ */
+class TWsatARGenerator {
+
+ /**
+ * Gets the current Db connection, the connection object is obtained from
+ * the TActiveRecordManager if connection is currently null.
+ * @return TDbConnection current db connection for this object.
+ */
+ private $_conn;
+
+ /**
+ * @return TActiveRecordGateway record table gateway.
+ */
+ private $_gateway;
+
+ /**
+ * Output folder where AR classes will be generated.
+ */
+ private $_op_file;
+
+ /**
+ * Class name prefix
+ */
+ private $_clas_prefix;
+
+ /**
+ * all table relations array
+ */
+ private $_relations;
+
+ function __construct() {
+ $ar_manager = TActiveRecordManager::getInstance();
+ $this->_conn = $ar_manager->getDbConnection();
+ $this->_conn->Active = true;
+ $this->_gateway = $ar_manager->getRecordGateway();
+ }
+
+ /**
+ * Destructor.
+ * Disconnect the db connection.
+ */
+ public function __destruct() {
+ if ($this->_conn !== null)
+ $this->_conn->Active = false;
+ }
+
+ public function setOpFile($op_file_namespace) {
+ $op_file = Prado::getPathOfNamespace($op_file_namespace);
+ if (empty($op_file)) {
+ throw new Exception("You need to fix your output folder namespace.");
+ }
+ if (!is_dir($op_file)) {
+ mkdir($op_file, 0777, true);
+ }
+ $this->_op_file = $op_file;
+ }
+
+ public function setClasPrefix($_clas_prefix) {
+ $this->_clas_prefix = $_clas_prefix;
+ }
+
+//-----------------------------------------------------------------------------
+ // <editor-fold defaultstate="collapsed" desc="Main APIs">
+ public function generate($tableName) {
+ $tableInfo = $this->_gateway->getTableInfo($this->_conn, $tableName);
+ if (count($tableInfo->getColumns()) === 0) {
+ throw new Exception("Unable to find table or view $tableName in " . $this->_conn->getConnectionString() . ".");
+ } else {
+ $properties = array();
+ foreach ($tableInfo->getColumns() as $field => $column)
+ $properties[] = $this->generateProperty($field, $column);
+ $toString = $this->_buildSmartToString($tableInfo);
+ }
+
+ $clasName = $this->_getProperClassName($tableName);
+ $class = $this->generateClass($properties, $tableName, $clasName, $toString);
+ $output = $this->_op_file . DIRECTORY_SEPARATOR . $clasName . ".php";
+ file_put_contents($output, $class);
+ }
+
+ public function generateAll() {
+ foreach ($this->_getAllTableNames() as $tableName) {
+ if ($tableName == "pradocache") {
+ continue;
+ }
+ $this->generate($tableName);
+ }
+ }
+
+ public function buildRelations() {
+ $this->_relations = array();
+ foreach ($this->_getAllTableNames() as $table_name) {
+ $tableInfo = $this->_gateway->getTableInfo($this->_conn, $table_name);
+ foreach ($tableInfo->getForeignKeys() as $fk_data) {
+ $owner_table = $fk_data["table"];
+ $slave_table = $table_name;
+ $fk_prop = key($fk_data["keys"]);
+
+ $this->_relations[$owner_table][] = array(
+ "prop_name" => strtolower($slave_table),
+ "rel_type" => "self::HAS_MANY",
+ "ref_class_name" => $this->_getProperClassName($slave_table),
+ "prop_ref" => $fk_prop
+ );
+
+ $this->_relations[$slave_table][] = array(
+ "prop_name" => strtolower($owner_table),
+ "rel_type" => "self::BELONGS_TO",
+ "ref_class_name" => $this->_getProperClassName($owner_table),
+ "prop_ref" => $fk_prop
+ );
+ }
+ }
+ }
+
+// </editor-fold>
+//-----------------------------------------------------------------------------
+ // <editor-fold defaultstate="collapsed" desc="Common Methods">
+
+ private function _getAllTableNames() {
+ $command = $this->_conn->createCommand("Show Tables");
+ $dataReader = $command->query();
+ $dataReader->bindColumn(1, $table);
+ $tables = array();
+ while ($dataReader->read()) {
+ $tables[] = $table;
+ }
+ return $tables;
+ }
+
+ private function _getProperClassName($tableName) {
+ $table_name_words = str_replace("_", " ", strtolower($tableName));
+ $final_conversion = str_replace(" ", "", ucwords($table_name_words));
+ return $this->_clas_prefix . $final_conversion;
+ }
+
+ public function renderAllTablesInformation() {
+ foreach ($this->_getAllTableNames() as $table_name) {
+ echo $table_name . "<br>";
+
+ $tableInfo = $this->_gateway->getTableInfo($this->_conn, $table_name);
+ echo "Table info:" . "<br>";
+ echo "<pre>";
+ var_dump($tableInfo);
+ echo "</pre>";
+ }
+ }
+
+//-----------------------------------------------------------------------------
+
+ protected function generateProperty($field, $column) {
+ $prop = '';
+ $name = '$' . $field;
+
+ /* TODO use in version 2.0 */
+ // $type = $column->getPHPType();
+
+ $prop .= "\tpublic $name;";
+ return $prop;
+ }
+
+ private function _renderRelations($tablename) {
+ if (!isset($this->_relations[$tablename])) {
+ return "";
+ }
+ $code = "\tpublic static \$RELATIONS = array (";
+ foreach ($this->_relations[$tablename] as $rel_data) {
+ $code .= "\n\t\t'" . $rel_data["prop_name"] . "' => array(" . $rel_data["rel_type"] . ", '" . $rel_data["ref_class_name"] . "', '" . $rel_data["prop_ref"] . "'),";
+ }
+ $code = substr($code, 0, -1);
+ $code .= "\n\t);";
+ return $code;
+ }
+
+ private function _buildSmartToString($tableInfo) {
+ $code = "\tpublic function __toString() {";
+ $property = "throw new THttpException(500, 'Not implemented yet.');";
+ try {
+ foreach ($tableInfo->getColumns() as $column) {
+ if (isset($column->IsPrimaryKey) && $column->IsPrimaryKey) {
+ $property = str_replace(array("`", "'", '"'), "", $column->ColumnName);
+ } elseif ($column->DbType == "varchar") {
+ $property = str_replace(array("`", "'", '"'), "", $column->ColumnName);
+ break;
+ }
+ }
+ } catch (Exception $ex) {
+
+ }
+ $code .= "\n\t\treturn \$this->$property;";
+ $code .= "\n\t}";
+ return $code;
+ }
+
+ protected function generateClass($properties, $tablename, $classname, $toString) {
+ $props = implode("\n", $properties);
+ $relations = $this->_renderRelations($tablename);
+ $date = date('Y-m-d h:i:s');
+ return <<<EOD
+<?php
+/**
+ * Auto generated by PRADO - WSAT on $date.
+ * @author prado_user_name
+ */
+class $classname extends TActiveRecord {
+
+ const TABLE='$tablename';
+
+$props
+
+ public static function finder(\$className=__CLASS__) {
+ return parent::finder(\$className);
+ }
+
+$relations
+
+$toString
+}
+?>
+EOD;
+ }
+
+// </editor-fold>
+}
+
+?>
diff --git a/framework/Wsat/TWsatService.php b/framework/Wsat/TWsatService.php
index de2bbdf6..3af34d49 100644
--- a/framework/Wsat/TWsatService.php
+++ b/framework/Wsat/TWsatService.php
@@ -1,61 +1,62 @@
-<?php
-
-/**
- * Description of TWsat
- * Inspired in both Microsoft Web Site Administration Tool(WSAT) and Yii's Gii.
- * @version 1.0
- * @author Daniel Sampedro darthdaniel85@gmail.com
- * @since Prado 3.3
- *
- * To use TWsatService, configure it in the application specification like following:
- * <code>
- * <services>
- * <service id="wsat" class="System.Wsat.TWsatService" Password="my_secret_password" />
- * </services>
- * </code>
- * ...and then you need to go to http://localhost/yoursite/index.php?wsat=TWsatLogin
- * and generate code and configure your site.
- */
-class TWsatService extends TPageService {
-
- private $_pass = '';
-
-//-----------------------------------------------------------------------------
- public function init($config) {
- if ($this->getApplication()->getMode() === TApplicationMode::Performance || $this->getApplication()->getMode() === TApplicationMode::Normal) {
- throw new TInvalidOperationException("You should not use Prado WSAT in any of the production modes.");
- }
- if (empty($this->_pass)) {
- throw new TConfigurationException("You need to specify the Password attribute.");
- }
- $this->setDefaultPage("TWsatHome");
- $this->_startThemeManager();
- parent::init($config);
- }
-
- public function getBasePath() {
- $basePath = Prado::getPathOfNamespace("System.Wsat.pages");
- return realpath($basePath);
- }
-
- private function _startThemeManager() {
- $themeManager = new TThemeManager;
- $themeManager->BasePath = "System.Wsat.themes";
- $url = Prado::getApplication()->getAssetManager()->publishFilePath(Prado::getPathOfNamespace('System.Wsat'));
- $themeManager->BaseUrl = $url . DIRECTORY_SEPARATOR . "themes";
-
- $themeManager->init(null);
- $this->setThemeManager($themeManager);
- }
-
- public function getPassword() {
- return $this->_pass;
- }
-
- public function setPassword($_pass) {
- $this->_pass = $_pass;
- }
-
-}
-
-?>
+<?php
+
+/**
+ * Description of TWsat
+ * Inspired in both Microsoft Web Site Administration Tool(WSAT) and Yii's Gii.
+ * @version 1.0
+ * @author Daniel Sampedro darthdaniel85@gmail.com
+ * @since Prado 3.3
+ *
+ * To use TWsatService, configure it in the application configuration file like following:
+ * <code>
+ * <services>
+ * ...
+ * <service id="wsat" class="System.Wsat.TWsatService" Password="my_secret_password" />
+ * </services>
+ * </code>
+ * ...and then you need to go to http://localhost/yoursite/index.php?wsat=TWsatLogin
+ * and generate code and configure your site.
+ */
+class TWsatService extends TPageService {
+
+ private $_pass = '';
+
+//-----------------------------------------------------------------------------
+ public function init($config) {
+ if ($this->getApplication()->getMode() === TApplicationMode::Performance || $this->getApplication()->getMode() === TApplicationMode::Normal) {
+ throw new TInvalidOperationException("You should not use Prado WSAT in any of the production modes.");
+ }
+ if (empty($this->_pass)) {
+ throw new TConfigurationException("You need to specify the Password attribute.");
+ }
+ $this->setDefaultPage("TWsatHome");
+ $this->_startThemeManager();
+ parent::init($config);
+ }
+
+ public function getBasePath() {
+ $basePath = Prado::getPathOfNamespace("System.Wsat.pages");
+ return realpath($basePath);
+ }
+
+ private function _startThemeManager() {
+ $themeManager = new TThemeManager;
+ $themeManager->BasePath = "System.Wsat.themes";
+ $url = Prado::getApplication()->getAssetManager()->publishFilePath(Prado::getPathOfNamespace('System.Wsat'));
+ $themeManager->BaseUrl = $url . DIRECTORY_SEPARATOR . "themes";
+
+ $themeManager->init(null);
+ $this->setThemeManager($themeManager);
+ }
+
+ public function getPassword() {
+ return $this->_pass;
+ }
+
+ public function setPassword($_pass) {
+ $this->_pass = $_pass;
+ }
+
+}
+
+?>
diff --git a/framework/Wsat/pages/TWsatGenerateAR.page b/framework/Wsat/pages/TWsatGenerateAR.page
index 3905d023..acd456fd 100644
--- a/framework/Wsat/pages/TWsatGenerateAR.page
+++ b/framework/Wsat/pages/TWsatGenerateAR.page
@@ -1,21 +1,31 @@
<com:TContent ID="Content">
- <div style="margin-left: 220px">
+ <div style="margin-left: 220px; font-size: 14px">
<div class="form_row">
- <com:TLabel Text="Table Name:" ForControl="table_name" style="margin-right: 14px" />
+ <com:TLabel Text="Table Name:" ForControl="table_name" style="margin-right: 24px" />
<com:TTextBox ID="table_name" Text="*" CssClass="in_text" />
+ <com:TRequiredFieldValidator ControlToValidate="table_name" Text="Table name cannot be blank." Display="Dynamic" />
</div>
<div class="form_row">
- <com:TLabel Text="Class Prefix:" ForControl="class_prefix" style="margin-right: 16px"/>
+ <com:TLabel Text="Class Prefix:" ForControl="class_prefix" style="margin-right: 25px"/>
<com:TTextBox ID="class_prefix" Text="AR_" CssClass="in_text" />
</div>
<div class="form_row">
- <com:TLabel Text="Output Folder:" ForControl="output_folder"/>
+ <com:TLabel Text="Output Folder:" ForControl="output_folder" style="margin-right: 8px"/>
<com:TTextBox ID="output_folder" Text="Application.App_Data.AR_Classes" CssClass="in_text" />
</div>
+
+ <div class="form_row">
+ <com:TLabel Text="Build Relations:" ForControl="build_rel"/>
+ <com:TCheckBox ID="build_rel" Checked="true" />
+ </div>
+
+ <com:TPanel ID="success_panel" Visible="false">
+ <com:TLabel ID="generation_msg" />
+ </com:TPanel>
<br/>
<div style="text-align: center">
- <com:TButton Text="Preview" OnClick="preview" />
+ <com:TButton Text="Preview" OnClick="preview" Visible="false" />
<com:TButton Text="Generate" OnClick="generate" />
</div>
</div>
diff --git a/framework/Wsat/pages/TWsatGenerateAR.php b/framework/Wsat/pages/TWsatGenerateAR.php
index 754cac5c..3d4291e2 100644
--- a/framework/Wsat/pages/TWsatGenerateAR.php
+++ b/framework/Wsat/pages/TWsatGenerateAR.php
@@ -1,33 +1,49 @@
-<?php
-
-/**
- * Description of Inicio
- *
- * @author daniels
- */
-Prado::using("System.Wsat.TWsatARGenerator");
-
-class TWsatGenerateAR extends TPage {
-
- public function onInit($param) {
- parent::onInit($param);
- }
-
- public function generate($sender) {
- $table_name = $this->table_name->Text;
-
- $ar_generator = new TWsatARGenerator();
- if ($table_name != "*") {
- $ar_generator->generate($table_name);
- } else {
- $ar_generator->generateAll();
- }
- }
-
- public function preview($sender) {
-
- }
-
-}
-
+<?php
+
+/**
+ * Description of Inicio
+ *
+ * @author daniels
+ */
+Prado::using("System.Wsat.TWsatARGenerator");
+
+class TWsatGenerateAR extends TPage {
+
+ public function generate($sender) {
+ if ($this->IsValid) {
+ $table_name = $this->table_name->Text;
+ $class_prefix = $this->class_prefix->Text;
+ $output_folder_ns = $this->output_folder->Text;
+
+ try {
+ $ar_generator = new TWsatARGenerator();
+ $ar_generator->setOpFile($output_folder_ns);
+ $ar_generator->setClasPrefix($class_prefix);
+
+ if ($this->build_rel->Checked) {
+ $ar_generator->buildRelations();
+ }
+ if ($table_name != "*") {
+ $ar_generator->generate($table_name);
+ } else {
+ $ar_generator->generateAll();
+ }
+ $this->success_panel->CssClass = "success_panel";
+ $this->generation_msg->Text = "The code has been generated successfully.";
+ } catch (Exception $ex) {
+ $this->success_panel->CssClass = "exception_panel";
+ $this->generation_msg->Text = $ex->getMessage();
+ }
+ $this->success_panel->Visible = true;
+ }
+ }
+
+ public function preview($sender) {
+// $ar_generator = new TWsatARGenerator();
+// $ar_generator->renderAllTablesInformation();
+ throw new THttpException(500, "Not implemented yet.");
+ }
+
+}
+
?> \ No newline at end of file
diff --git a/framework/Wsat/pages/TWsatLogin.page b/framework/Wsat/pages/TWsatLogin.page
index b256d719..d0a94f2a 100644
--- a/framework/Wsat/pages/TWsatLogin.page
+++ b/framework/Wsat/pages/TWsatLogin.page
@@ -29,9 +29,10 @@
<div class="login_form">
<com:TLabel Text="Please enter your password:" ForControl="password"/><br/>
<com:TTextBox ID="password" TextMode="Password" style="margin: 5px" /><br/>
- <com:TRequiredFieldValidator ControlToValidate="password" Text="Password cannot be blank." /><br/>
-
- <com:TButton Text="Enter" OnClick="login" />
+ <com:TRequiredFieldValidator ControlToValidate="password" ValidationGroup="loginGroup" Text="Password cannot be blank." /><br/>
+ <com:TCustomValidator ControlToValidate="password" ValidationGroup="loginGroup" OnServerValidate="validatePassword" Text="Incorrect password." />
+
+ <com:TButton Text="Enter" ValidationGroup="loginGroup" OnClick="login" />
</div>
<div id="footer">
diff --git a/framework/Wsat/pages/TWsatLogin.php b/framework/Wsat/pages/TWsatLogin.php
index 7435d75d..0bbdc53f 100644
--- a/framework/Wsat/pages/TWsatLogin.php
+++ b/framework/Wsat/pages/TWsatLogin.php
@@ -1,30 +1,31 @@
-<?php
-
-/**
- * Description of Inicio
- *
- * @author daniels
- */
-class TWsatLogin extends TPage {
-
- public function login() {
- $config_pass = $this->getService()->getPassword();
- $user_pass = $this->password->Text;
-
- if ($user_pass === $config_pass) {
- $this->Session["wsat_password"] = $config_pass;
-
- $authManager = $this->Application->getModule('auth');
- $url = $authManager->ReturnUrl;
- if (empty($url)) {
- $url = $this->Service->constructUrl('TWsatHome');
- }
- $this->Response->redirect($url);
- } else {
- echo "user or pass wrong";
- }
- }
-
-}
-
+<?php
+
+/**
+ * Description of Inicio
+ *
+ * @author daniels
+ */
+class TWsatLogin extends TPage {
+
+ public function login() {
+ if ($this->IsValid) {
+ $this->Session["wsat_password"] = $this->getService()->getPassword();
+
+ $authManager = $this->Application->getModule('auth');
+ $url = $authManager->ReturnUrl;
+ if (empty($url)) {
+ $url = $this->Service->constructUrl('TWsatHome');
+ }
+ $this->Response->redirect($url);
+ }
+ }
+
+ public function validatePassword($sender, $param) {
+ $config_pass = $this->getService()->getPassword();
+ $user_pass = $this->password->Text;
+ $param->IsValid = $user_pass === $config_pass;
+ }
+
+}
+
?> \ No newline at end of file
diff --git a/framework/Wsat/themes/PradoSoft/main.css b/framework/Wsat/themes/PradoSoft/main.css
index 6c609e95..c35a87d8 100644
--- a/framework/Wsat/themes/PradoSoft/main.css
+++ b/framework/Wsat/themes/PradoSoft/main.css
@@ -1,133 +1,151 @@
-html, body{
- margin: 0px;
- padding: 0px;
- font-family: 'Lucida Grande', Verdana, Geneva, Lucida, Helvetica, Arial, sans-serif;
- font-weight: normal;
-}
-
-#header {
- font-size:25px;
- font-weight:bold;
- color: #666;
-}
-
-.logo{
- width: 204px;
- height:100px;
- background-image: url('imgs/pradologo.gif');
- background-repeat: no-repeat;
- float: left;
-}
-
-.mantisbg{
- width: 221px;
- height: 100px;
- background-image: url('imgs/mantisbg.jpg');
- background-repeat: no-repeat;
- float: right;
-}
-
-.mainmenu {
- padding:10px;
- padding-right:10px;
- background:#EDEDED;
- border-bottom: 1px solid #A6A6A6;
- border-top: 1px solid #DCDCDC;
- color:white;
- text-align:right;
- font-size: 10pt;
-}
-
-.mainmenu a {
- color:#737373;
- text-decoration:none;
-}
-
-.mainmenu a:hover {
- color: #FF0000;
-}
-
-#toc {
- background-color: #F3F3F3;
- width:220px;
- padding:0px 10px 0px 10px;
- float: left;
-}
-
-#content {
- padding: 1em 1em 1em 1em;
- line-height: 135%;
- float: left;
-}
-
-.topic {
- font-size: 9pt;
- padding: 0px 0px 0px 0px;
-}
-
-.topic div {
- background-image: url('imgs/arrowdown.gif');
- background-repeat: no-repeat;
- background-position: left center;
- margin: 0px;
- font-size: 8pt;
- font-weight:bold;
- color:#2A480A;
- padding: 5px;
- padding-left: 15px;
- border-top: 1px solid #fff;
- border-bottom: 1px solid #E2E2E2;
-}
-
-.topic ul
-{
- margin: 0px;
- padding: 0px;
-}
-
-.topic ul li
-{
- list-style: none;
- margin: 0px;
- padding: 5px;
- padding-left: 15px;
- border-bottom: 1px dotted #D8D8D8;
-}
-
-.topic a {
- color:#4F811A;
- font-size: 8pt;
- text-decoration: none;
-}
-
-.topic a:hover {
- color:#2A480A;
-}
-
-/* form styles */
-.form_row{
- margin: 10px;
-}
-
-.in_text{
- width: 250px;
-}
-
-.login_form{
- text-align: center;
- margin: 30px auto;
- border: 1px solid red;
- border-radius: 5px;
- padding: 10px;
- width: 250px;
- font-size: 11px;
-}
-
-#footer {
- clear:both;
- color: gray;
- font-size:8pt;
- text-align:center;
- margin-top:25px;
- padding:10px;
+html, body{
+ margin: 0px;
+ padding: 0px;
+ font-family: 'Lucida Grande', Verdana, Geneva, Lucida, Helvetica, Arial, sans-serif;
+ font-weight: normal;
+}
+
+#header {
+ font-size:25px;
+ font-weight:bold;
+ color: #666;
+}
+
+.logo{
+ width: 204px;
+ height:100px;
+ background-image: url('imgs/pradologo.gif');
+ background-repeat: no-repeat;
+ float: left;
+}
+
+.mantisbg{
+ width: 221px;
+ height: 100px;
+ background-image: url('imgs/mantisbg.jpg');
+ background-repeat: no-repeat;
+ float: right;
+}
+
+.mainmenu {
+ padding:10px;
+ padding-right:10px;
+ background:#EDEDED;
+ border-bottom: 1px solid #A6A6A6;
+ border-top: 1px solid #DCDCDC;
+ color:white;
+ text-align:right;
+ font-size: 10pt;
+}
+
+.mainmenu a {
+ color:#737373;
+ text-decoration:none;
+}
+
+.mainmenu a:hover {
+ color: #FF0000;
+}
+
+#toc {
+ background-color: #F3F3F3;
+ width:220px;
+ padding:0px 10px 0px 10px;
+ float: left;
+}
+
+#content {
+ padding: 1em 1em 1em 1em;
+ line-height: 135%;
+ float: left;
+}
+
+.topic {
+ font-size: 9pt;
+ padding: 0px 0px 0px 0px;
+}
+
+.topic div {
+ background-image: url('imgs/arrowdown.gif');
+ background-repeat: no-repeat;
+ background-position: left center;
+ margin: 0px;
+ font-size: 8pt;
+ font-weight:bold;
+ color:#2A480A;
+ padding: 5px;
+ padding-left: 15px;
+ border-top: 1px solid #fff;
+ border-bottom: 1px solid #E2E2E2;
+}
+
+.topic ul
+{
+ margin: 0px;
+ padding: 0px;
+}
+
+.topic ul li
+{
+ list-style: none;
+ margin: 0px;
+ padding: 5px;
+ padding-left: 15px;
+ border-bottom: 1px dotted #D8D8D8;
+}
+
+.topic a {
+ color:#4F811A;
+ font-size: 8pt;
+ text-decoration: none;
+}
+
+.topic a:hover {
+ color:#2A480A;
+}
+
+/* form styles */
+.form_row{
+ margin: 10px;
+}
+
+.in_text{
+ width: 250px;
+}
+
+.login_form{
+ text-align: center;
+ margin: 30px auto;
+ border: 1px solid red;
+ border-radius: 5px;
+ padding: 10px;
+ width: 250px;
+ font-size: 11px;
+}
+
+.success_panel{
+ background-color: #C5FBBD;
+ border: 1px solid #76C376;
+ padding: 10px;
+ margin: 10px 0;
+ border-radius: 5px;
+ text-align: center;
+}
+
+.exception_panel{
+ background-color: #ff6666;
+ border: 1px solid red;
+ padding: 10px;
+ margin: 10px 0;
+ border-radius: 5px;
+ text-align: center;
+}
+
+#footer {
+ clear:both;
+ color: gray;
+ font-size:8pt;
+ text-align:center;
+ margin-top:25px;
+ padding:10px;
} \ No newline at end of file