/**
  * We will output style tags and such, but fieldset styling is not well supported across browsers.
  */
 protected function GetInnerHtml()
 {
     $strHtml = parent::GetInnerHtml();
     if (!empty($this->strLegend)) {
         $strHtml = '<legend>' . $this->strLegend . '</legend>' . _nl() . $strHtml;
     }
     return $strHtml;
 }
 /**
  * @param QControl|QControlBase $objControl   QControl for which the actions have to be rendered
  * @param string                $strEventName Name of the event for which the actions have to be rendered
  * @param QAction[]             $objActions   Array of actionss
  *
  * @return null|string
  * @throws Exception
  */
 public static function RenderActions(QControl $objControl, $strEventName, $objActions)
 {
     $strToReturn = '';
     $strJqUiProperty = null;
     if ($objControl->ActionsMustTerminate) {
         $strToReturn .= ' event.preventDefault();' . _nl();
     }
     if ($objActions && count($objActions)) {
         foreach ($objActions as $objAction) {
             if ($objAction->objEvent->EventName != $strEventName) {
                 throw new Exception('Invalid Action Event in this entry in the ActionArray');
             }
             if ($objAction->objEvent instanceof QJqUiPropertyEvent) {
                 $strJqUiProperty = $objAction->objEvent->JqProperty;
             }
             if ($objAction->objEvent->Delay > 0) {
                 $strCode = sprintf(" qcubed.setTimeout('%s', \$j.proxy(function(){%s},this), %s);", $objControl->ControlId, _nl() . _indent(trim($objAction->RenderScript($objControl))) . _nl(), $objAction->objEvent->Delay);
             } else {
                 $strCode = ' ' . $objAction->RenderScript($objControl);
             }
             // Add Condition (if applicable)
             if (strlen($objAction->objEvent->Condition)) {
                 $strCode = sprintf(' if (%s) {%s}', $objAction->objEvent->Condition, _nl() . _indent(trim($strCode)) . _nl());
             }
             $strCode .= _nl();
             // Append it to the Return Value
             $strToReturn .= $strCode;
         }
     }
     $strToReturn = _nl() . _indent($strToReturn);
     if (strlen($strToReturn)) {
         if ($strJqUiProperty) {
             $strOut = sprintf('$j("#%s").%s("option", {%s: function(event, ui){%s}});', $objControl->getJqControlId(), $objControl->getJqSetupFunction(), $strJqUiProperty, $strToReturn);
         } elseif ($objControl instanceof QControlProxy) {
             if ($objControl->TargetControlId) {
                 // Deprecated.
                 $strOut = sprintf('$j("#%s").on("%s", function(event, ui){%s});', $objControl->TargetControlId, $strEventName, $strToReturn);
             } else {
                 $strOut = sprintf('$j("#%s").on("%s", "[data-qpxy=\'%s\']", function(event, ui){%s});', $objControl->Form->FormId, $strEventName, $objControl->ControlId, $strToReturn);
             }
         } else {
             $strOut = sprintf('$j("#%s").on("%s", function(event, ui){%s});', $objControl->getJqControlId(), $strEventName, $strToReturn);
         }
         if (isset($strOut)) {
             if (!QApplication::$Minimize) {
                 // Render a comment
                 $strOut = _nl() . _nl() . sprintf('/*** Event: %s  Control Type: %s, Control Name: %s, Control Id: %s  ***/', $strEventName, get_class($objControl), $objControl->Name, $objControl->ControlId) . _nl() . _indent($strOut) . _nl() . _nl();
             }
             return $strOut;
         }
     }
     return null;
 }
 /**
  * Returns the caption string which can be used for the table.
  *
  * @return string
  */
 protected function RenderCaption()
 {
     $strHtml = '';
     if ($this->strCaption) {
         $strHtml .= '<caption>' . QApplication::HtmlEntities($this->strCaption) . '</caption>' . _nl();
     }
     return $strHtml;
 }
    /**
     * Renders the end of the form, including the closing form and body tags.
     * Renders the html for hidden controls.
     * @param bool $blnDisplayOutput should the output be returned or directly printed to screen.
     *
     * @return null|string
     * @throws QCallerException
     */
    public function RenderEnd($blnDisplayOutput = true)
    {
        // Ensure that RenderEnd() has not yet been called
        switch ($this->intFormStatus) {
            case QFormBase::FormStatusUnrendered:
                throw new QCallerException('$this->RenderBegin() was never called');
            case QFormBase::FormStatusRenderBegun:
                break;
            case QFormBase::FormStatusRenderEnded:
                throw new QCallerException('$this->RenderEnd() has already been called');
                break;
            default:
                throw new QCallerException('FormStatus is in an unknown status');
        }
        $strHtml = '';
        // This will be the final output
        /**** Render any controls that get automatically rendered ****/
        foreach ($this->GetAllControls() as $objControl) {
            if ($objControl->AutoRender && !$objControl->Rendered) {
                $strRenderMethod = $objControl->PreferredRenderMethod;
                $strHtml .= $objControl->{$strRenderMethod}(false) . _nl();
            }
        }
        /**** Prepare Javascripts ****/
        // Clear included javascript array since we are completely redrawing the page
        $this->strIncludedJavaScriptFileArray = array();
        $strControlIdToRegister = array();
        $strEventScripts = '';
        // Add form level javascripts and libraries
        $strJavaScriptArray = $this->ProcessJavaScriptList($this->GetFormJavaScripts());
        QApplication::AddJavaScriptFiles($strJavaScriptArray);
        $strFormJsFiles = QApplication::RenderFiles();
        // Render the form-level javascript files separately
        // Go through all controls and gather up any JS or CSS to run or Form Attributes to modify
        foreach ($this->GetAllControls() as $objControl) {
            if ($objControl->Rendered || $objControl->ScriptsOnly) {
                $strControlIdToRegister[] = $objControl->ControlId;
                /* Note: GetEndScript may cause the control to register additional commands, or even add javascripts, so those should be handled after this. */
                if ($strControlScript = $objControl->GetEndScript()) {
                    $strControlScript = JavaScriptHelper::TerminateScript($strControlScript);
                    // Add comments for developer version of output
                    if (!QApplication::$Minimize) {
                        // Render a comment
                        $strControlScript = _nl() . _nl() . sprintf('/*** EndScript -- Control Type: %s, Control Name: %s, Control Id: %s  ***/', get_class($objControl), $objControl->Name, $objControl->ControlId) . _nl() . _indent($strControlScript);
                    }
                    $strEventScripts .= $strControlScript;
                }
            }
            // Include the javascripts specified by each control.
            if ($strScriptArray = $this->ProcessJavaScriptList($objControl->JavaScripts)) {
                QApplication::AddJavaScriptFiles($strScriptArray);
            }
            // Include any StyleSheets?  The control would have a
            // comma-delimited list of stylesheet files to include (if applicable)
            if ($strScriptArray = $this->ProcessStyleSheetList($objControl->StyleSheets)) {
                QApplication::AddStyleSheets(array_keys($strScriptArray));
            }
            // Form Attributes?
            if ($objControl->FormAttributes) {
                QApplication::ExecuteControlCommand($this->strFormId, 'attr', $objControl->FormAttributes);
                foreach ($objControl->FormAttributes as $strKey => $strValue) {
                    if (!array_key_exists($strKey, $this->strFormAttributeArray)) {
                        $this->strFormAttributeArray[$strKey] = $strValue;
                    } else {
                        if ($this->strFormAttributeArray[$strKey] != $strValue) {
                            $this->strFormAttributeArray[$strKey] = $strValue;
                        }
                    }
                }
            }
        }
        // Add grouping commands to events (Used for deprecated drag and drop, but not removed yet)
        foreach ($this->objGroupingArray as $objGrouping) {
            $strGroupingScript = $objGrouping->Render();
            if (strlen($strGroupingScript) > 0) {
                $strGroupingScript = JavaScriptHelper::TerminateScript($strGroupingScript);
                $strEventScripts .= $strGroupingScript;
            }
        }
        /*** Build the javascript block ****/
        // Start with variable settings and initForm
        $strEndScript = sprintf('qc.initForm("%s"); ', $this->strFormId);
        // Register controls
        if ($strControlIdToRegister) {
            $strEndScript .= sprintf("qc.regCA(%s); \n", JavaScriptHelper::toJsObject($strControlIdToRegister));
        }
        // Design mode event
        if (defined('__DESIGN_MODE__') && __DESIGN_MODE__ == 1) {
            // attach an event listener to the form to send context menu selections to the designer dialog for processing
            $strEndScript .= sprintf('$j("#%s").on("contextmenu", "[id]", 
						function(event) {
							$j("#qconnectoreditdlg").trigger("qdesignerclick", 
								[{id: event.target.id ? event.target.id : $j(event.target).parents("[id]").attr("id"), for: $j(event.target).attr("for")}]
							);
							return false;
						}
					);', $this->FormId);
        }
        // Add any application level js commands.
        // This will include high and medimum level commands
        $strEndScript .= QApplication::RenderJavascript(true);
        // Add the javascript coming from controls and events just after the medium level commands
        $strEndScript .= ';' . $strEventScripts;
        // Add low level commands and other things that need to execute at the end
        $strEndScript .= ';' . QApplication::RenderJavascript(false);
        // Create Final EndScript Script
        $strEndScript = sprintf('<script type="text/javascript">$j(document).ready(function() { %s; });</script>', $strEndScript);
        /**** Render the HTML itself, appending the javascript we generated above ****/
        foreach ($this->GetAllControls() as $objControl) {
            if ($objControl->Rendered) {
                $strHtml .= $objControl->GetEndHtml();
            }
            $objControl->ResetFlags();
            // Make sure controls are serialized in a reset state
        }
        $strHtml .= $strFormJsFiles . _nl();
        // Add form level javascript files
        // put javascript environment defines up early for use by other js files.
        $strHtml .= '<script type="text/javascript">' . sprintf('qc.baseDir = "%s"; ', __VIRTUAL_DIRECTORY__ . __SUBDIRECTORY__) . sprintf('qc.jsAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __JS_ASSETS__) . sprintf('qc.phpAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __PHP_ASSETS__) . sprintf('qc.cssAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __CSS_ASSETS__) . sprintf('qc.imageAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __IMAGE_ASSETS__) . '</script>' . _nl();
        $strHtml .= QApplication::RenderFiles() . _nl();
        // add plugin and control js files
        // Render hidden controls related to the form
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormId" id="Qform__FormId" value="%s" />', $this->strFormId) . _nl();
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormControl" id="Qform__FormControl" value="" />') . _nl();
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormEvent" id="Qform__FormEvent" value="" />') . _nl();
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormParameter" id="Qform__FormParameter" value="" />') . _nl();
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormCallType" id="Qform__FormCallType" value="" />') . _nl();
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormUpdates" id="Qform__FormUpdates" value="" />') . _nl();
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormCheckableControls" id="Qform__FormCheckableControls" value="" />') . _nl();
        // Serialize and write out the formstate
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormState" id="Qform__FormState" value="%s" />', QForm::Serialize(clone $this)) . _nl();
        // close the form tag
        $strHtml .= "</form>";
        // Add the JavaScripts rendered above
        $strHtml .= $strEndScript;
        // close the body tag
        if ($this->blnRenderedBodyTag) {
            $strHtml .= '</body>';
        }
        /**** Cleanup ****/
        // Update Form Status
        $this->intFormStatus = QFormBase::FormStatusRenderEnded;
        // Display or Return
        if ($blnDisplayOutput) {
            if (!QApplication::$CliMode) {
                print $strHtml;
            }
            return null;
        } else {
            if (!QApplication::$CliMode) {
                return $strHtml;
            } else {
                return '';
            }
        }
    }
 /**
  * Returns the given string formatted as an html comment that will go on its own line.
  * @param string 	$strText
  * @param bool 		$blnRemoveOnMinimize
  * @return string
  */
 public static function Comment($strText, $blnRemoveOnMinimize = true)
 {
     if ($blnRemoveOnMinimize && QApplication::$Minimize) {
         return '';
     }
     return _nl() . '<!-- ' . $strText . ' -->' . _nl();
 }
 private static function RenderCommandArray(array $commandArray)
 {
     $strScript = '';
     foreach ($commandArray as $command) {
         if (isset($command['script'])) {
             // a script to use eval on
             $strScript .= sprintf('%s;', $command['script']) . _nl();
         } elseif (isset($command['selector'])) {
             // a control function
             if (is_array($command['selector'])) {
                 $strSelector = sprintf('"%s", "%s"', $command['selector'][0], $command['selector'][1]);
             } else {
                 $strSelector = '"' . $command['selector'] . '"';
             }
             if ($params = $command['params']) {
                 $objParams = new QJsParameterList($params);
                 $strParams = $objParams->toJsObject();
             } else {
                 $strParams = '';
             }
             $strScript .= sprintf('jQuery(%s).%s(%s);', $strSelector, $command['func'], $strParams) . _nl();
         } elseif (isset($command['func'])) {
             // a function call
             if ($params = $command['params']) {
                 $objParams = new QJsParameterList($params);
                 $strParams = $objParams->toJsObject();
             } else {
                 $strParams = '';
             }
             $strScript .= sprintf('%s(%s);', $command['func'], $strParams) . _nl();
         }
     }
     return $strScript;
 }
 /**
  * Returns the HTML-Code for a single Item
  * 
  * @param QListItem $objItem
  * @return string resulting HTML
  */
 protected function GetItemHtml(QListItem $objItem)
 {
     // The Default Item Style
     if ($this->objItemStyle) {
         $objStyler = clone $this->objItemStyle;
     } else {
         $objStyler = new QListItemStyle();
     }
     // Apply any Style Override (if applicable)
     if ($objStyle = $objItem->ItemStyle) {
         $objStyler->Override($objStyle);
     }
     $objStyler->SetHtmlAttribute('value', $objItem->Empty ? '' : $objItem->Id);
     if ($objItem->Selected) {
         $objStyler->SetHtmlAttribute('selected', 'selected');
     }
     $strHtml = QHtml::RenderTag('option', $objStyler->RenderHtmlAttributes(), QApplication::HtmlEntities($objItem->Name), false, true) . _nl();
     return $strHtml;
 }
 /**
  * Utility function to make sure a script is terminated with a semicolon.
  *
  * @param $strScript
  * @return string
  */
 public static function TerminateScript($strScript)
 {
     if (!$strScript) {
         return '';
     }
     if (!($strScript = trim($strScript))) {
         return '';
     }
     if (substr($strScript, -1) != ';') {
         $strScript .= ';';
     }
     return $strScript . _nl();
 }