diff options
| author | Daniel <darthdaniel85@gmail.com> | 2013-11-22 15:25:30 -0500 | 
|---|---|---|
| committer | Daniel <darthdaniel85@gmail.com> | 2013-11-22 15:25:30 -0500 | 
| commit | ab6effd64caefa732ef0994d6c3048f5cd474bf6 (patch) | |
| tree | 73f4e568295f4d7625fc16af9ce03c58bbbaab2a | |
| parent | 85ca63b0896be3d12a098b44b5ec0c65a5b76a6c (diff) | |
WSAT beta release.
| -rw-r--r-- | framework/Wsat/TWsatARGenerator.php | 368 | ||||
| -rw-r--r-- | framework/Wsat/TWsatService.php | 123 | ||||
| -rw-r--r-- | framework/Wsat/pages/TWsatGenerateAR.page | 20 | ||||
| -rw-r--r-- | framework/Wsat/pages/TWsatGenerateAR.php | 80 | ||||
| -rw-r--r-- | framework/Wsat/pages/TWsatLogin.page | 7 | ||||
| -rw-r--r-- | framework/Wsat/pages/TWsatLogin.php | 59 | ||||
| -rw-r--r-- | framework/Wsat/themes/PradoSoft/main.css | 282 | 
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 | 
