Plasma GitLab Archive
Projects Blog Knowledge

<?xml version="1.0" encoding="ISO-8859-1"?>

<!--
  - <COPYRIGHT>
  - Copyright 2003 Gerd Stolpmann
  -
  - <GPL>
  - This file is part of WTimer.
  - 
  - WTimer is free software; you can redistribute it and/or modify
  - it under the terms of the GNU General Public License as published by
  - the Free Software Foundation; either version 2 of the License, or
  - (at your option) any later version.
  -
  - WTimer is distributed in the hope that it will be useful,
  - but WITHOUT ANY WARRANTY; without even the implied warranty of
  - 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 WDialog; if not, write to the Free Software
  - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  - </>
  -->

<!--  $Id: editor.ui,v 1.5 2003/03/23 11:59:14 gerd Exp $
   -  ======================================================================
   - 
  -->

<!-- This file defines the dialog "editor". -->

<ui:dialog name="editor" start-page="timesheet-chrono">
  <ui:variable name="session" type="dialog"/>
    <!-- The session pseudo dialog, see session.ui -->

  <ui:variable name="scroll_position"/>
    <!-- See explanations in definitions.ui, basic-grid -->

  <ui:enumeration name="bool">
    <ui:enum internal="no"/>
    <ui:enum internal="yes"/>
  </ui:enumeration>

  <ui:variable name="modified">
    <!-- Is there any unsaved modification of the data? yes/no/load.
       - "load" means that the data have not yet been loaded from db.
      -->
    <ui:string-value>load</ui:string-value>
  </ui:variable>

  <ui:variable name="checksum">
    <!-- The checksum of the contents as saved into the database. -->
  </ui:variable>

  <ui:variable name="read-only">
    <!-- Is the sheet read-only? yes/no -->
    <!--&editor-read-only;-->          <!-- Test data for this variable -->
  </ui:variable>

  <ui:variable name="ins-number">
    <!-- For the "Insert #" box -->
    <ui:string-value>1</ui:string-value>
  </ui:variable>

  <!-- Test data for the following variables can be found in the file
     - editor-test.xml, in the form of XML entities
    -->

  <ui:variable name="grouped-by-days" associative="yes">
    <!-- Mapping from date literals to strings that contain the record IDs
       - to display for the dates. E.g.
       - "1970-01-01" ==> "4 5 6"
       -->
    <!--&editor-grouped-by-days;-->     <!-- Test data for this variable -->
  </ui:variable>


  <ui:variable name="grouped-by-projects" associative="yes">
    <!-- Mapping from group names to strings that contain the record IDs
       - to display for the dates. E.g.
       - "XYZ" ==> "4 5 6"
       -->
    <!--&editor-grouped-by-projects;-->  <!-- Test data for this variable -->
  </ui:variable>


  <ui:variable name="selection" associative="yes" type="bool">
    <!-- For every row there is a selection box (checkbox). This variable
       - stores for every row whether it is selected. Rows are identified
       - by record IDs or by date literals. The latter mean the "append
       - to day" selection boxes.
      -->
    <!--&editor-selection;-->           <!-- Test data for this variable -->
  </ui:variable>

  <ui:variable name="date" associative="yes">
    <!-- Mapping from record IDs to date literals -->
    <!--&editor-date;-->                 <!-- Test data for this variable -->
  </ui:variable>

  <ui:variable name="time-from" associative="yes">
    <!-- Mapping from record IDs to the "time from" values -->
    <!--&editor-time-from;-->           <!-- Test data for this variable -->
  </ui:variable>

  <ui:variable name="time-to" associative="yes">
    <!-- Mapping from record IDs to the "time to" values -->
    <!--&editor-time-to;-->             <!-- Test data for this variable -->
  </ui:variable>

  <ui:variable name="duration" associative="yes">
    <!-- Mapping from record IDs to the durations -->
    <!--&editor-duration;-->            <!-- Test data for this variable -->
  </ui:variable>

  <ui:variable name="project" associative="yes">
    <!-- Mapping from record IDs to the project names -->
    <!--&editor-project;-->             <!-- Test data for this variable -->
  </ui:variable>

  <ui:variable name="description" associative="yes">
    <!-- Mapping from record IDs to the descriptions -->
    <!--&editor-description;-->         <!-- Test data for this variable -->
  </ui:variable>

  <ui:variable name="selected-project" type="dynamic-enumerator"/>
    <!-- This variable is needed for formal reasons -->

  <ui:variable name="available-projects" type="dynamic-enumerator">
    <!-- The projects to select from in the projects popup window -->
    <!--&editor-available-projects;-->       <!-- Test data for this variable -->
  </ui:variable>

  <ui:enumeration name="message">
    <ui:enum internal="saved"
             external="The sheet has been saved into the database."/>
    <ui:enum internal="error-syntax"
             external="Some fields are filled with incorrect data. 
                       The wrong fields are highlighted with a thick red 
                       border. Please correct them."/>
    <ui:enum internal="error-missing-selection"
             external="Please select one or more rows first!"/>
    <ui:enum internal="error-invalid-date"
             external="It is not possible to display the demanded month."/>
  </ui:enumeration>

  <ui:variable name="message" type="message">
    <!--&editor-message;-->              <!-- Test data for this variable -->
  </ui:variable>

  <ui:variable name="error-boxes" type="dynamic-enumerator">
    <!-- Enumerates the boxes that must be highlighted. Every box has
       - a name:
       - "from-<ID>": Wrong "From" box for this ID
       - "to-<ID>": Wrong "To" box for this ID
       - "duration-<ID>": Wrong "Duration" box for this ID
       - "ins-number": Wrong "Insert #" box
      -->
    <!--&editor-error-boxes; -->          <!-- Test data for this variable -->
  </ui:variable>

  <ui:variable name="deferred-dialog" type="dialog"/>
    <!-- While the page "unsaved" is displayed, this variable stores the
       - dialog the user tried to call
      -->


  <ui:page name="timesheet-chrono">
    <!-- This page is displayed when the chronological time sheet is 
       - selected
      -->
    <t:basic-grid have_scroll_position="yes">
      <p:html-head>
	<ui:popup page="popup_projects"/>
      </p:html-head>
      <p:html-foot>
	<script language="javascript">init_checkboxes();</script>
      </p:html-foot>
      <p:nav-col>
	<t:timesheet-nav view-chrono="yes"/>
      </p:nav-col>
      <p:headline>
	<t:timesheet-head/>
      </p:headline>
      <p:main-col>
	<t:timesheet-chrono-main/>
      </p:main-col>
    </t:basic-grid>
  </ui:page>


  <ui:page name="timesheet-by-project">
    <!-- This page is displayed when the project-oriented time sheet is 
       - selected
      -->
    <t:basic-grid>
      <p:nav-col>
	<t:timesheet-nav view-by-project="yes"/>
      </p:nav-col>
      <p:headline>
	<t:timesheet-head/>
      </p:headline>
      <p:main-col>
	<t:timesheet-by-project-main/>
      </p:main-col>
    </t:basic-grid>
  </ui:page>


  <ui:page name="popup_projects" popup="yes">
    <!-- The popup window for the "..." buttons. -->
    <t:popup-grid>
      <p:headline>Select Project</p:headline>
      <p:main-col>
	<div>
	  <ui:select variable="selected-project" base="available-projects"
	             class="projects-select"
	             id="popup-select"
	             size="7" 
                     ondblclick="window.opener.select_project(document)"
	    /></div>
	<div>
	  <input type="button" value="OK" class="projects-button"
	         onclick="window.opener.select_project(document)"/>
	  <input type="button" value="Close" class="projects-button"
	         onclick="window.opener.close_popup()"/>
        </div>
      </p:main-col>
    </t:popup-grid>
  </ui:page>


  <ui:page name="unsaved">
    <!-- When somebody tries to leave the editor without saving -->
    <t:basic-grid>
      <p:nav-col>
	<!-- empty nav-col: this is a modal dialog -->
      </p:nav-col>
      <p:headline>
	<t:timesheet-head/>
      </p:headline>
      <p:main-col>
	<q:message int="confirm-unsaved">
	  <div>
	    You try to leave the editor, but there are unsaved changes.
	    Do you want to save the sheet now?
	  </div>
	  <div class="buttonbox">
	    <ui:button name="unsaved-save"    label="Save sheet"/>
	    <ui:button name="unsaved-discard" label="Discard changes"/>
	    <ui:button name="unsaved-cancel"  label="Cancel"/>
	  </div>
	</q:message>
      </p:main-col>
    </t:basic-grid>
  </ui:page>


  <!-- ERROR HANDLING -->

  <!-- See also ocaml class error_behaviour that uses the following
       definitions
    -->

  <ui:variable name="runtime-error"/>

  <ui:page name="runtime-error">
    <t:basic-grid>
      <p:nav-col>
	<!-- empty nav-col: this is a modal dialog -->
      </p:nav-col>
      <p:headline>
	<t:timesheet-head/>
      </p:headline>
      <p:main-col>
	<t:error errid="$[runtime-error]"/>
	<ui:button name="cont-error" label="Continue"/>
      </p:main-col>
    </t:basic-grid>
  </ui:page>

</ui:dialog>


<!-- ********************************************************************** -->

<!-- timesheet-nav: The navigation bar for timesheets -->

<ui:template name="timesheet-nav" 
             from-caller="view-chrono view-by-project
                          _paste_disabeled
                         ">
  <ui:default name="view-chrono">no</ui:default>
  <ui:default name="view-by-project">no</ui:default>
  <!-- The following parameters are normally not passed by the caller,
     - and the default value applies:
    -->
  <ui:default name="_paste_disabeled"
    ><ui:cond>
      <ui:ifvar variable="session.clipboard" value="">yes</ui:ifvar>
      <ui:true>no</ui:true>
    </ui:cond
 ></ui:default>


  <q:nav-section head="File">
    <ui:if value1="$[read-only]" value2="yes" op="ne">
      <q:nav-entry title="Save changes to database (ALT-S)">
	<q:applink label="Save" name="file-save" accesskey="S"/>
      </q:nav-entry>
    </ui:if>
    <t:file-menu except="file-editor"/>
  </q:nav-section>

  <ui:if value1="$[read-only]" value2="yes" op="ne">
    <q:nav-section head="Edit">
      <q:nav-entry title="Insert new row into timesheet (ALT-I)">
	<t:applink name="edit-ins" accesskey="I" label="Insert"/>
      </q:nav-entry>
      <q:nav-entry title="Number of rows to insert">
	<q:applink-appendix>
	  <q:timesheet-check-error box="ins-number">
	    Insert #<ui:text variable="ins-number" 
	                     onchange="check_number(this, 1, 99)"
	                     size="2"/>
	  </q:timesheet-check-error>
	</q:applink-appendix>
      </q:nav-entry>
      <q:nav-entry title="Delete selected rows from timesheet (ALT-D)">
	<q:applink label="Delete" name="edit-del" accesskey="D"/>
      </q:nav-entry>
      <q:nav-entry title="Copy selected rows to buffer (ALT-C)">
	<q:applink label="Copy" name="edit-copy" accesskey="C"/>
      </q:nav-entry>
      <q:nav-entry title="Cut selected rows, and store them in buffer (ALT-X)">
	<q:applink label="Cut" name="edit-cut" accesskey="X"/>
      </q:nav-entry>
      <q:nav-entry title="Paste rows in buffer (ALT-V)">
	<q:applink label="Paste" name="edit-paste" accesskey="V"
	           disabled="${_paste_disabeled}"/>
      </q:nav-entry>
    </q:nav-section>

    <script language="javascript">
    <![CDATA[
    with (document.uiform) {
	elements['button_edit-del'].onclick  = check_selection;
	elements['button_edit-copy'].onclick = check_selection;
	elements['button_edit-cut'].onclick  = check_selection;
	if (elements['button_edit-paste'] != null) {
	    elements['button_edit-paste'].onclick = check_selection_paste;
	}
    }
    ]]>
    </script>
  </ui:if>

  <q:nav-section head="View">
    <q:nav-entry title="Show entries in chronological order (ALT-H)">
      <q:applink label="Chrono" name="view-chrono" accesskey="H"
	goto="timesheet-chrono" emphasis="${view-chrono}"/>
    </q:nav-entry>
    <q:nav-entry title="Show entries ordered by projects (ALT-O)">
      <q:applink label="By Projects" name="view-proj" accesskey="O"
	goto="timesheet-by-project" emphasis="${view-by-project}"/>
    </q:nav-entry>
  </q:nav-section>

  <q:nav-section head="Time Travel">
    <q:nav-entry title="Show previous month (ALT-P)">
      <q:applink label="Previous" name="time-prev" accesskey="P"/>
    </q:nav-entry>
    <q:nav-entry title="Show next month (ALT-N)">
      <q:applink label="Next" name="time-next" accesskey="N"/>
    </q:nav-entry>
  </q:nav-section>
</ui:template>

<!-- ********************************************************************** -->

<ui:template name="timesheet-head">
  <!-- The headline for this dialog: -->
  $[session.current-date/year], $[session.current-date/month-en]
  <ui:if value1="$[read-only]" value2="yes">
    (read-only)
  </ui:if>
  <t:head-modified-flag/>
  <t:head-info-box/>
</ui:template>

<!-- ********************************************************************** -->

<!-- Now templates for the chronological view follow -->


<ui:template name="timesheet-chrono-main">
  <div><a href="#help">Help</a><br/>&nbsp;</div>
  <ui:enumerate variable="message" template="message"/>
  <ui:iterate variable="grouped-by-days" template="timesheet-day"/>

  <div class="help">
    <a name="help"/>
    <div>This dialog allows you to edit the current month of the current
      time sheet. There are two views: "Chrono" (as shown) to modify
      the sheet, and "By projects" to sum up the time spent on the various
      projects.</div>

    <div>To <em>add</em> a new row, check the place where to insert or
      append the row, and press "Insert". You can add more than one row
      by increasing the "Insert #" number. The new rows (like all other
      changes) must be saved (button "Save") to get permanent.</div>

    <div>To <em>delete</em> rows, check the rows to delete, and press
      "Delete". (Checking the "append" places does not have any effect.)
    </div>

    <div>To <em>modify</em> rows, just change the text in the input
      boxes. Input errors are detected immediately if Javascript is
      turned on, otherwise the next time you press a button.</div>

    <div>To <em>copy</em> rows, check the rows to copy, and press "Copy".
      This writes the contents of the rows to the internal clipboard.
      Check the place where to insert the copy, and press "Paste".
      The clipboard keeps its contents when you change the sheet in the
      meantime. The clipboard does not remember where day breaks are,
      however.</div>

    <div>To <em>move</em> rows, check the rows to move, and press "Cut".
      This moves the contents of the rows to the internal clipboard.
      Check the place where to finally put the rows, and press "Paste".
    </div>

    <div>Your changes of the contents of the sheet are made permanent when
      you press the "Save" button. Until then, you can undo all changes by
      just leaving the sheet (e.g. by "Time Travel"). Just press "Discard"
      in the confirmation dialog.
    </div>

    <div>
      If your web browser supports DOM level 2 very well, you can select
      a range of rows by clicking at the first row, and shift-clicking
      at the last row. This selects (or deselects) all rows between, too.
    </div>

  </div>

</ui:template>



<ui:template name="timesheet-day" from-caller="int">
  <!-- int: Current date of the day in ISO format (YYYY-MM-DD) -->
  <table class="timesheet-block" bgcolor="#CDBA96">
    <!-- Define titles for columns [DOES NOT WORK] -->
<!--
    <col title="Select for edit operation"/>
    <col title="Start time"/>
    <col title="End time"/>
    <col title="Duration"/>
    <col title="Project identifier"/>
    <col title="Description"/>
-->
    <!-- General headline: Which day is displayed -->
    <tr>
      <td></td>
      <td colspan="6">
	<div class="timesheet-block-head">
	  <!-- Note: ${int/weekday-en} is an abbreviated notation for
	       <ui:encoding enc="weekday-en">$int</ui:encoding>
            -->
	  <b>${int/weekday-en}, ${int/month-en} ${int/mday-en}</b>
	</div>
      </td>
    </tr>
    <!-- Rows displaying the records of this day -->
    <ui:iterate variable="grouped-by-days" index="$int" 
                template="timesheet-day-row">
      <ui:iter-empty>
	<ui:if value1="$[read-only]" value2="yes">
	  <tr>
	    <td>&nbsp;</td>
	    <td colspan="6" class="timesheet-append">(Empty)</td>
	  </tr>
	</ui:if>
      </ui:iter-empty>
    </ui:iterate>
    <!-- Footer -->
    <ui:if value1="$[read-only]" value2="yes" op="ne">
      <t:timesheet-day-foot date="$int"/>
    </ui:if>
  </table>
  <t:legacy-vspacer size="20"/>
</ui:template>


<!-- Note: The "onchange" handler is only a convenience feature. Bad input
     is rejected by the server anyway, but reporting bad time formats
     immediately is quite helpful. - The "onchange" handler is called:
     - when the user clicks at another text box, or
     - when a button is pressed (because the button gets the focus)
     AND the value has changed.

     Note that there is also a global submit handler.
     The javascript functions are defined in "definitions.js".
  -->

<ui:template name="timesheet-day-row" from-caller="ext">
  <!-- ext: Database ID of the row -->
  <tr>
    <td>
      <ui:if value1="$[read-only]" value2="yes" op="ne">
	<ui:checkbox variable="selection" index="$ext" value="yes"
	  wtimer-selector="yes"
	  title="Select for edit operation"
	  />
      </ui:if>
    </td>
    <td align="center">
      <ui:cond>
	<ui:if value1="$[read-only]" value2="yes">
	  $[assoc(time-from,$ext)]
	</ui:if>
	<ui:true>
	  <q:timesheet-check-error box="from-$ext">
	    <ui:text variable="time-from" index="$ext" 
	      title="Start time"
	      onchange="check_time_string(this)"
	      class="timesheet-input" size="5" maxlength="5"/>
	  </q:timesheet-check-error>
	</ui:true>
      </ui:cond>
    </td>
    <td>-</td>
    <td align="center">
      <ui:cond>
	<ui:if value1="$[read-only]" value2="yes">
	  $[assoc(time-to,$ext)]
	</ui:if>
	<ui:true>
	  <q:timesheet-check-error box="to-$ext">
	    <ui:text variable="time-to" index="$ext" 
	      title="End time"
	      onchange="check_time_string(this)"
	  class="timesheet-input" size="5" maxlength="5"/>
	  </q:timesheet-check-error>
	</ui:true>
      </ui:cond>
    </td>
    <td align="center">
      <ui:cond>
	<ui:if value1="$[read-only]" value2="yes">
	  ($[assoc(duration,$ext)]),
	</ui:if>
	<ui:true>
	  <q:timesheet-check-error box="duration-$ext">
	    <ui:text variable="duration" index="$ext" 
	      title="Duration"
	      onchange="check_time_string(this)"
	      class="timesheet-input" size="5" maxlength="5"/>
	  </q:timesheet-check-error>
	</ui:true>
      </ui:cond>
    </td>
    <td>
      <ui:cond>
	<ui:if value1="$[read-only]" value2="yes">
	  $[assoc(project,$ext)]:
	</ui:if>
	<ui:true>
	  <ui:text variable="project" 
	    title="Project identifier"
	    onchange="set_modified_flag()"
	    id="projectcell-$ext"
	    class="timesheet-input" index="$ext" size="10"/>
	  <ui:if value1="$[session.js-enabled]" value2="yes">
	    <input type="button" value="..." class="timesheet-popup" 
	           onclick="popup_projects('$ext')"
	           id="projectbutton-$ext"/>
	    <!-- Set a CLICK event handler by the best available method: -->
	    <ui:special>
	      <script language="javascript">
		configure_popup_projects('$ext');
	      </script>
	    </ui:special>
	  </ui:if>
	</ui:true>
      </ui:cond>
    </td>
    <td>
      <ui:cond>
	<ui:if value1="$[read-only]" value2="yes">
	  $[assoc(description,$ext)]
	</ui:if>
	<ui:true>
	  <ui:text variable="description" 
	    onchange="set_modified_flag()"
	    title="Description"
	    class="timesheet-input" index="$ext" size="35"/>
	</ui:true>
      </ui:cond>
    </td>
  </tr>
</ui:template>


<ui:template name="timesheet-day-foot" from-caller="date">
  <!-- date: Current date of the day in ISO format (YYYY-MM-DD) -->
  <tr>
    <td>
      <ui:checkbox variable="selection" index="day-$date" value="yes"
	wtimer-appender="yes"
	title="Select for edit operation ('insert', 'paste')"
	/>
    </td>
    <td colspan="6" class="timesheet-append">
      <!-- &rArr; is not supported by many browsers, so use an image -->
      <img src="&static-url-prefix;rArr.png" width="12" height="12"/>
      <!-- <ui:special>&amp;rArr;</ui:special> -->
      append rows ("insert", "paste")</td>
  </tr>
</ui:template>


<ui:template name="timesheet-check-error" from-caller="box body">
  <ui:cond>
    <ui:ifvar variable="error-boxes" value="$box" op="contains">
      <!-- This must also work for legacy grid, so we use a table -->
      <table cellpadding="5" bgcolor="red" class="timesheet-error">
	<tr>
	  <td>$body</td>
	</tr>
      </table>
    </ui:ifvar>
    <ui:true>
      $body
    </ui:true>
  </ui:cond>
</ui:template>

<!-- ********************************************************************** -->

<!-- Now templates for the project-oriented view follow -->

<ui:template name="timesheet-by-project-main">
  <ui:enumerate variable="message" template="message"/>
  <ui:iterate variable="grouped-by-projects" template="timesheet-project"/>
</ui:template>

<ui:template name="timesheet-project" from-caller="int">
  <!-- int: Current project identifier -->
  <table class="timesheet-block" bgcolor="#CDBA96">
    <!-- General headline: Which project is displayed -->
    <tr>
      <td colspan="2">&nbsp;</td>
      <td colspan="4">
	<div class="timesheet-block-head">
	  <b>Project $int</b>
	</div>
      </td>
    </tr>
    <!-- Sample rows -->
    <ui:iterate variable="grouped-by-projects" index="$int" 
                template="timesheet-project-row"/>
    <!-- Footer -->
    <t:timesheet-project-foot project="$int"/>
  </table>
  <t:legacy-vspacer size="20"/>
</ui:template>



<ui:template name="timesheet-project-row" from-caller="ext">
  <!-- ext: Database ID of the row -->
  <tr>
    <td title="Date" align="right">
      <ui:encode enc="weekday-en"
        ><ui:dynamic variable="date" index="$ext"/></ui:encode>,
    </td>
    <td title="Date" align="left">
      <ui:encode enc="mday-en"
        ><ui:dynamic variable="date" index="$ext"/></ui:encode>
    </td>
    <td title="Start time" class="timesheet-input" align="right">
      <ui:dynamic variable="time-from" index="$ext"/>
    </td>
    <td title="End time" class="timesheet-input" align="right">
      <ui:dynamic variable="time-to" index="$ext"/>
    </td>
    <td title="Duration" class="timesheet-input" align="right">
      <ui:dynamic variable="duration" index="$ext"/>
    </td>
    <td title="Description" class="timesheet-input">
      <ui:dynamic variable="description" index="$ext"/>&nbsp;
    </td>
  </tr>
</ui:template>


<ui:template name="timesheet-project-foot" from-caller="project">
  <!-- project: the project name -->
  <tr>
    <td colspan="2" align="right">
      Sum
    </td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td title="Sum of $project" class="timesheet-input" align="right">
      <ui:dynamic variable="duration" index="project-$project"/>
    </td>
    <td>&nbsp;</td>
  </tr>
</ui:template>

<!-- ******************* For Emacs: ********************* -->
<!--
Local Variables:
mode: xml
sgml-parent-document: ("main.ui" "ui:application" "ui:dialog")
End:
-->

This web site is published by Informatikbüro Gerd Stolpmann
Powered by Caml