SF.net SVN: geany:[4640] branches/bs2

elextr at users.sourceforge.net elextr at xxxxx
Sat Feb 6 10:02:36 UTC 2010


Revision: 4640
          http://geany.svn.sourceforge.net/geany/?rev=4640&view=rev
Author:   elextr
Date:     2010-02-06 10:02:36 +0000 (Sat, 06 Feb 2010)

Log Message:
-----------
Add design spec and a temporary Pyton prototype of the configure
dialog for the build system.

Modified Paths:
--------------
    branches/bs2/ChangeLog

Added Paths:
-----------
    branches/bs2/doc/build_system_design_spec.html
    branches/bs2/scripts/build_dialog_prototype.py

Modified: branches/bs2/ChangeLog
===================================================================
--- branches/bs2/ChangeLog	2010-02-06 06:58:57 UTC (rev 4639)
+++ branches/bs2/ChangeLog	2010-02-06 10:02:36 UTC (rev 4640)
@@ -1,3 +1,10 @@
+2010-02-06  Lex Trotman  <elextr.at.gmail.dot.com>
+
+ * doc/build_system_design_spec.html, scripts/build_dialog_prototype.py
+   Add design spec and a temporary Pyton prototype of the configure
+   dialog for the build system.
+
+
 2010-02-01  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>
 
  * src/symbols.c:

Added: branches/bs2/doc/build_system_design_spec.html
===================================================================
--- branches/bs2/doc/build_system_design_spec.html	                        (rev 0)
+++ branches/bs2/doc/build_system_design_spec.html	2010-02-06 10:02:36 UTC (rev 4640)
@@ -0,0 +1,1743 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.5.3" />
+<title>Geany Build System Changes</title>
+<style type="text/css">
+/* Debug borders */
+p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
+/*
+  border: 1px solid red;
+*/
+}
+
+body {
+  margin: 1em 5% 1em 5%;
+}
+
+a {
+  color: blue;
+  text-decoration: underline;
+}
+a:visited {
+  color: fuchsia;
+}
+
+em {
+  font-style: italic;
+  color: navy;
+}
+
+strong {
+  font-weight: bold;
+  color: #083194;
+}
+
+tt {
+  color: navy;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  color: #527bbd;
+  font-family: sans-serif;
+  margin-top: 1.2em;
+  margin-bottom: 0.5em;
+  line-height: 1.3;
+}
+
+h1, h2, h3 {
+  border-bottom: 2px solid silver;
+}
+h2 {
+  padding-top: 0.5em;
+}
+h3 {
+  float: left;
+}
+h3 + * {
+  clear: left;
+}
+
+div.sectionbody {
+  font-family: serif;
+  margin-left: 0;
+}
+
+hr {
+  border: 1px solid silver;
+}
+
+p {
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+  margin-top: 0;
+}
+
+pre {
+  padding: 0;
+  margin: 0;
+}
+
+span#author {
+  color: #527bbd;
+  font-family: sans-serif;
+  font-weight: bold;
+  font-size: 1.1em;
+}
+span#email {
+}
+span#revnumber, span#revdate, span#revremark {
+  font-family: sans-serif;
+}
+
+div#footer {
+  font-family: sans-serif;
+  font-size: small;
+  border-top: 2px solid silver;
+  padding-top: 0.5em;
+  margin-top: 4.0em;
+}
+div#footer-text {
+  float: left;
+  padding-bottom: 0.5em;
+}
+div#footer-badges {
+  float: right;
+  padding-bottom: 0.5em;
+}
+
+div#preamble {
+  margin-top: 1.5em;
+  margin-bottom: 1.5em;
+}
+div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.admonitionblock {
+  margin-top: 2.0em;
+  margin-bottom: 2.0em;
+  margin-right: 10%;
+  color: #606060;
+}
+
+div.content { /* Block element content. */
+  padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+  color: #527bbd;
+  font-family: sans-serif;
+  font-weight: bold;
+  text-align: left;
+  margin-top: 1.0em;
+  margin-bottom: 0.5em;
+}
+div.title + * {
+  margin-top: 0;
+}
+
+td div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content + div.title {
+  margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+  background: #ffffee;
+  border: 1px solid silver;
+  padding: 0.5em;
+}
+
+div.listingblock > div.content {
+  border: 1px solid silver;
+  background: #f4f4f4;
+  padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+  padding-left: 1.0em;
+  margin-left: 1.0em;
+  margin-right: 10%;
+  border-left: 5px solid #dddddd;
+  color: #777777;
+}
+
+div.quoteblock > div.attribution {
+  padding-top: 0.5em;
+  text-align: right;
+}
+
+div.verseblock > pre.content {
+  font-family: inherit;
+}
+div.verseblock > div.attribution {
+  padding-top: 0.75em;
+  text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+  text-align: left;
+}
+
+div.admonitionblock .icon {
+  vertical-align: top;
+  font-size: 1.1em;
+  font-weight: bold;
+  text-decoration: underline;
+  color: #527bbd;
+  padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+  padding-left: 0.5em;
+  border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+  border-left: 3px solid #dddddd;
+  padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; }
+a.image:visited { color: white; }
+
+dl {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+dt {
+  margin-top: 0.5em;
+  margin-bottom: 0;
+  font-style: normal;
+  color: navy;
+}
+dd > *:first-child {
+  margin-top: 0.1em;
+}
+
+ul, ol {
+    list-style-position: outside;
+}
+ol.arabic {
+  list-style-type: decimal;
+}
+ol.loweralpha {
+  list-style-type: lower-alpha;
+}
+ol.upperalpha {
+  list-style-type: upper-alpha;
+}
+ol.lowerroman {
+  list-style-type: lower-roman;
+}
+ol.upperroman {
+  list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+  margin-top: 0.1em;
+  margin-bottom: 0.1em;
+}
+
+div.tableblock > table {
+  border: 3px solid #527bbd;
+}
+thead, p.table.header {
+  font-family: sans-serif;
+  font-weight: bold;
+}
+tfoot {
+  font-weight: bold;
+}
+td > div.verse {
+  white-space: pre;
+}
+p.table {
+  margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+  border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+  border-left-style: none;
+  border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+  border-top-style: none;
+  border-bottom-style: none;
+}
+
+
+div.hdlist {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+div.hdlist tr {
+  padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+  font-weight: bold;
+}
+td.hdlist1 {
+  vertical-align: top;
+  font-style: normal;
+  padding-right: 0.8em;
+  color: navy;
+}
+td.hdlist2 {
+  vertical-align: top;
+}
+div.hdlist.compact tr {
+  margin: 0;
+  padding-bottom: 0;
+}
+
+.comment {
+  background: yellow;
+}
+
+.footnote, .footnoteref {
+  font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+  vertical-align: super;
+}
+
+#footnotes {
+  margin: 20px 0 20px 0;
+  padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+  margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+  border: none;
+  border-top: 1px solid silver;
+  height: 1px;
+  text-align: left;
+  margin-left: 0;
+  width: 20%;
+  min-width: 100px;
+}
+
+
+ at media print {
+  div#footer-badges { display: none; }
+}
+
+div#toc {
+  margin-bottom: 2.5em;
+}
+
+div#toctitle {
+  color: #527bbd;
+  font-family: sans-serif;
+  font-size: 1.1em;
+  font-weight: bold;
+  margin-top: 1.0em;
+  margin-bottom: 0.1em;
+}
+
+div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+div.toclevel2 {
+  margin-left: 2em;
+  font-size: 0.9em;
+}
+div.toclevel3 {
+  margin-left: 4em;
+  font-size: 0.9em;
+}
+div.toclevel4 {
+  margin-left: 6em;
+  font-size: 0.9em;
+}
+/* Workarounds for IE6's broken and incomplete CSS2. */
+
+div.sidebar-content {
+  background: #ffffee;
+  border: 1px solid silver;
+  padding: 0.5em;
+}
+div.sidebar-title, div.image-title {
+  color: #527bbd;
+  font-family: sans-serif;
+  font-weight: bold;
+  margin-top: 0.0em;
+  margin-bottom: 0.5em;
+}
+
+div.listingblock div.content {
+  border: 1px solid silver;
+  background: #f4f4f4;
+  padding: 0.5em;
+}
+
+div.quoteblock-attribution {
+  padding-top: 0.5em;
+  text-align: right;
+}
+
+pre.verseblock-content {
+  font-family: inherit;
+}
+div.verseblock-attribution {
+  padding-top: 0.75em;
+  text-align: left;
+}
+
+div.exampleblock-content {
+  border-left: 3px solid #dddddd;
+  padding-left: 0.5em;
+}
+
+/* IE6 sets dynamically generated links as visited. */
+div#toc a:visited { color: blue; }
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+window.onload = function(){asciidoc.footnotes();}
+var asciidoc = {  // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+  function getText(el) {
+    var text = "";
+    for (var i = el.firstChild; i != null; i = i.nextSibling) {
+      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+        text += i.data;
+      else if (i.firstChild != null)
+        text += getText(i);
+    }
+    return text;
+  }
+
+  function TocEntry(el, text, toclevel) {
+    this.element = el;
+    this.text = text;
+    this.toclevel = toclevel;
+  }
+
+  function tocEntries(el, toclevels) {
+    var result = new Array;
+    var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
+    // Function that scans the DOM tree for header elements (the DOM2
+    // nodeIterator API would be a better technique but not supported by all
+    // browsers).
+    var iterate = function (el) {
+      for (var i = el.firstChild; i != null; i = i.nextSibling) {
+        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+          var mo = re.exec(i.tagName);
+          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+          }
+          iterate(i);
+        }
+      }
+    }
+    iterate(el);
+    return result;
+  }
+
+  var toc = document.getElementById("toc");
+  var entries = tocEntries(document.getElementById("content"), toclevels);
+  for (var i = 0; i < entries.length; ++i) {
+    var entry = entries[i];
+    if (entry.element.id == "")
+      entry.element.id = "_toc_" + i;
+    var a = document.createElement("a");
+    a.href = "#" + entry.element.id;
+    a.appendChild(document.createTextNode(entry.text));
+    var div = document.createElement("div");
+    div.appendChild(a);
+    div.className = "toclevel" + entry.toclevel;
+    toc.appendChild(div);
+  }
+  if (entries.length == 0)
+    toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+  var cont = document.getElementById("content");
+  var noteholder = document.getElementById("footnotes");
+  var spans = cont.getElementsByTagName("span");
+  var refs = {};
+  var n = 0;
+  for (i=0; i<spans.length; i++) {
+    if (spans[i].className == "footnote") {
+      n++;
+      // Use [\s\S] in place of . so multi-line matches work.
+      // Because JavaScript has no s (dotall) regex flag.
+      note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+      noteholder.innerHTML +=
+        "<div class='footnote' id='_footnote_" + n + "'>" +
+        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+        n + "</a>. " + note + "</div>";
+      spans[i].innerHTML =
+        "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+        "' title='View footnote' class='footnote'>" + n + "</a>]";
+      var id =spans[i].getAttribute("id");
+      if (id != null) refs["#"+id] = n;
+    }
+  }
+  if (n == 0)
+    noteholder.parentNode.removeChild(noteholder);
+  else {
+    // Process footnoterefs.
+    for (i=0; i<spans.length; i++) {
+      if (spans[i].className == "footnoteref") {
+        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+        href = href.match(/#.*/)[0];  // Because IE return full URL.
+        n = refs[href];
+        spans[i].innerHTML =
+          "[<a href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+      }
+    }
+  }
+}
+
+}
+/*]]>*/
+</script>
+</head>
+<body style="max-width:40em">
+<div id="header">
+<h1>Geany Build System Changes</h1>
+<span id="author">Lex Trotman</span><br />
+<span id="email"><tt><<a href="mailto:geany-devel at uvena.de">geany-devel at uvena.de</a>></tt></span><br />
+<span id="revdate">January 2010</span>
+</div>
+<div id="content">
+<div id="preamble">
+<div class="sectionbody">
+<div class="paragraph"><p>This document describes the proposed changes to the Geany build system
+specification and design.  This document describes changes from the last
+released version of Geany (0.18), but also reflects the lessons learned
+from a first implementation attempt.</p></div>
+</div>
+</div>
+<h2 id="_purpose">Purpose</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>The purpose of the changes is to improve the flexibility and
+configurability of the actions performed by the Build menu.</p></div>
+<div class="paragraph"><p>The main use cases which triggered the changes were:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+support for running more genralised commands to support build tools
+  other than make
+</p>
+</li>
+<li>
+<p>
+ability to store customisations in project files to support projects
+  using different tool sets
+</p>
+</li>
+<li>
+<p>
+ability to set working directories for customised commands
+</p>
+</li>
+<li>
+<p>
+GUI setup of all customisations
+</p>
+</li>
+<li>
+<p>
+ability for plugins to affect the build process
+</p>
+</li>
+</ul></div>
+</div>
+<h2 id="_requirements">Requirements</h2>
+<div class="sectionbody">
+<h3 id="_operations">Operations</h3><div style="clear:left"></div>
+<div class="paragraph"><p>Since the terms action, event, command etc. have specific meanings the
+term <strong>operation</strong> will be used in this document to describe what happens
+when a Build menu item is activated.</p></div>
+<div class="paragraph"><p>An operation has a configurable label with mnemonic, to be shown on
+the Build menu.  The label must allow for translations to be provided
+and an optional icon to be shown on the build menu and the toolbar.</p></div>
+<div class="paragraph"><p>Other than this icon there is no interface between operations and
+the toolbar, as the toolbar should work by activating the
+appropriate Build menu item and so does not need an interface to
+the operations.</p></div>
+<div class="paragraph"><p>The Build menu must be able to trigger operations which are:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+internal to the Geany or plugin code, initially:
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+next error
+</p>
+</li>
+<li>
+<p>
+previous error
+</p>
+</li>
+<li>
+<p>
+show configuration dialog
+</p>
+</li>
+</ul></div>
+</li>
+<li>
+<p>
+programs to be executed external to Geany.
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>External operations must be able to configure the following attributes:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+the command to be executed in a shell
+</p>
+</li>
+<li>
+<p>
+a working directory where the command is to be executed
+</p>
+</li>
+<li>
+<p>
+how the command output is handled:
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+output parsed by Geany to the Build message tab (re-named
+    Compiler tab) and a regex must be configurable for that parsing (or
+    fallback to coded parsing ?still needed?)
+</p>
+</li>
+<li>
+<p>
+output to a terminal (VTE or the configured terminal)
+</p>
+</li>
+<li>
+<p>
+output to Geany’s terminal (or lost if Geany is started fron a
+    Gnome/KDE/Xfce etc menu)
+</p>
+</li>
+</ul></div>
+</li>
+<li>
+<p>
+a menu label if the command is stopable, the menu item will change to
+  this label while the command is running and the icon will change to
+  the standard stop icon.  Activating the menu item again will attempt
+  to stop the running command.
+</p>
+</li>
+<li>
+<p>
+a sensitivity group, only one operation of a sensitivity group can
+  run at any time, all menu items with operations in the same group are
+  set insensitive while a command in the group is running.  The menu
+  item which triggered the operation will also be insensitive if the
+  command is not stopable.
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>All commands whose output is to be parsed will automatically be in
+one sensitivity group so that only one parser stream is required at
+any one time.</p></div>
+<div class="paragraph"><p>An empty or undefined working directory is an error rather than
+default to some value.  This ensures that commands don’t accidently
+do something you don’t want soemwhere you don’t want it.</p></div>
+<div class="paragraph"><p>The command and working directory fields will accept the following
+substitutions:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+%c{…} - the text returned from a dialog box
+</p>
+</li>
+<li>
+<p>
+%d - the full path of the directory of the current document
+</p>
+</li>
+<li>
+<p>
+%e - the filename of the current document without extension
+</p>
+</li>
+<li>
+<p>
+%f - the filename of the current document
+</p>
+</li>
+<li>
+<p>
+%p - the project base path as configured in the open project
+</p>
+</li>
+<li>
+<p>
+%s - the current file separator (i.e. %d%s%f = full path to the
+  current document)
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>The substitutions %d, %e, %f will substitute nothing if there is no
+current named document.  The substitution %p will substitute
+nothing if no project is open.</p></div>
+<div class="paragraph"><p>The dialog box generated by %c will have the menu label as the
+title, it will contain a text entry with the text inside the {}
+displayed above the entry.  The dialog will have an Ok button which
+causes the text in the entry to replace the %c{..} and a Cancel
+button which will replace the %c{…} with nothing.  The dialog
+will default to the last entry and remember previous entries.  A missing
+{} will display no text.</p></div>
+<h3 id="_configuration_sources">Configuration Sources</h3><div style="clear:left"></div>
+<div class="paragraph"><p>The configuration of operations must come from multiple sources:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+defaults
+</p>
+</li>
+<li>
+<p>
+system configuration files (installed with Geany)
+</p>
+</li>
+<li>
+<p>
+user configuration files
+</p>
+</li>
+<li>
+<p>
+the Geany program or plugins
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>Each source must be able to provide configuration for a specific
+filetype and for all filetypes not specifically configured.</p></div>
+<div class="paragraph"><p>When more than one source has an operation configured for the same
+build menu item the one that will be used is chosen using a simple
+fixed priority order, from first choice to last:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+configuration by Geany or a plugin for the filetype of the current
+  document
+</p>
+</li>
+<li>
+<p>
+configuration by Geany or a plugin for any filetype
+</p>
+</li>
+<li>
+<p>
+user configuration for the filetype of the current document
+</p>
+</li>
+<li>
+<p>
+user configuration for any filetype
+</p>
+</li>
+<li>
+<p>
+system configuration for the filetype of the current document
+</p>
+</li>
+<li>
+<p>
+system configuration for any filetype
+</p>
+</li>
+<li>
+<p>
+default values
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>The first source with a configuration present will provide all
+values, if a value is not set for an attribute in a configuration
+then a blank string, off or the first of a list will be used as
+appropraite to the type of attribute..</p></div>
+<h3 id="_menu_layout">Menu Layout</h3><div style="clear:left"></div>
+<div class="paragraph"><p>The build menu must be able to be organised in to several groups of
+items with separators between them.  Grouping similar operations
+provides a better user experience in a menu which has the potential
+to contain widely differing operations.  The number of groups and
+the number of operations in them must be configurable but a maximum
+must be set at startup.  The default and minimum will be 5 sections
+sized from the top of the menu 3, 4, 2, 2, 1.</p></div>
+<div class="paragraph"><p>The default menu layout is:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+current file related operations section, language dependent e.g. for
+  the C language:
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+Compile current file
+</p>
+</li>
+<li>
+<p>
+Link current file
+</p>
+</li>
+</ul></div>
+</li>
+<li>
+<p>
+multi file related operations section, language independent:
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+Make
+</p>
+</li>
+<li>
+<p>
+Make Custom Target
+</p>
+</li>
+<li>
+<p>
+Make Object
+</p>
+</li>
+</ul></div>
+</li>
+<li>
+<p>
+error navigation operations section:
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+Next error
+</p>
+</li>
+<li>
+<p>
+Previous error
+</p>
+</li>
+</ul></div>
+</li>
+<li>
+<p>
+execution related operations section, language independent:
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+Execute current file
+</p>
+</li>
+</ul></div>
+</li>
+<li>
+<p>
+Configuration operations section:
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+Show configuration dialog
+</p>
+</li>
+</ul></div>
+</li>
+</ul></div>
+<h3 id="_configuration">Configuration</h3><div style="clear:left"></div>
+<div class="paragraph"><p>Other than the number of sections and their sizes, all configuration
+shall be available from the GUI.</p></div>
+<div class="paragraph"><p>Only one dialog shall be used for the whole menu.  The dialog shall
+indicate the form that the menu will take after the changes are applied.</p></div>
+<div class="paragraph"><p>The dialog shall have more than one level of detail so that it will
+not be overwhelming on first use.</p></div>
+<div class="paragraph"><p>The dialog must be able to edit the configuration for user and
+project sources for both the filetype of the current document and
+the filetype independent settings.  To prevent the filetype changing the
+dialog may be modal.</p></div>
+<div class="paragraph"><p>At full detail the dialog must be able to show other configuration
+sources that may influence the operation that a menu item will
+perform (eg system or default), however these cannot be changed by
+the dialog.</p></div>
+</div>
+<h2 id="_design">Design</h2>
+<div class="sectionbody">
+<h3 id="_menu_operation">Menu Operation</h3><div style="clear:left"></div>
+<div class="paragraph"><p>Just call <tt>do_it</tt> on the appropriate current operation.</p></div>
+<div class="paragraph"><p>Each menu item with a %c has a separate dialog memory.</p></div>
+<h3 id="_addressing_menu_items">Addressing Menu Items</h3><div style="clear:left"></div>
+<div class="paragraph"><p>Since the size of the sections of the menu can vary, just specifying
+a number within the menu won’t work, enlarging a section would bring
+the first item of the next section into the preceding section.</p></div>
+<div class="paragraph"><p>So address by section number and item within section.</p></div>
+<div class="paragraph"><p>Since section sizes differ an operation list will be an array of
+pointers to arrays of pointers to operation objects, not a 2d array.</p></div>
+<h3 id="_addressing_of_operations">Addressing of Operations</h3><div style="clear:left"></div>
+<div class="paragraph"><p>Operation lists need to be addressed by current (ie which one is in use),
+and by source.  Sources have filetype independent and filetype dependent
+contents.</p></div>
+<div class="paragraph"><p>Operations are stored as lists addressed by menu item (ie section,
+number).</p></div>
+<div class="paragraph"><p>Current can be a build.c static operation list pointer,
+<tt>current_operations</tt>.  This is updated by the operation setter on
+any change to an operation that might change which operation is
+used for a menu item and is used to update the menu and to select
+operation to run on activation.</p></div>
+<div class="paragraph"><p>Filetype independent sources just need a build.c static pointer each,
+<tt>internal_operations</tt>, <tt>project_operations</tt>, <tt>user_operations</tt>,
+<tt>system_operations</tt>, <tt>default_operations</tt>.</p></div>
+<div class="paragraph"><p>The simplest way of storing filetype dependent data is to add it to
+the existing filetype structure.  Add fields with names the same as
+the first four above in the "plugins don’t use this" part of the
+structure.</p></div>
+<div class="paragraph"><p>For use outside build.c provide a function <tt>operation
+*build_get_operations(source)</tt> and <tt>operation
+*build_get_filetype_operations(source)</tt> where source is an enum.</p></div>
+<div class="paragraph"><p>IF these are actually a performance problem they can be made macros but
+since that would increase coupling, until proven guilty will be functions.</p></div>
+<h3 id="_operation_object">Operation Object</h3><div style="clear:left"></div>
+<div class="paragraph"><p>This is the main structure representing an operation.
+Operation structure should be opaque with getter/setter.  The setter
+should trigger gui update if needed and therefore should be
+multi-field. Updating all fields that are to change at once allows
+consistency checking.  Updating one field at a time may result in
+inconsistent states between field updates, (ie update one field
+creates an inconsistent state until another field is updated to
+match) so it is difficult to know when it is safe to to check
+consistency and when it is safe to update the GUI. Also batching reduces
+the number of potential GUI updates.</p></div>
+<div class="paragraph"><p>In C, typesafe variable argument calls are not possible, instead use
+a transaction technique, ie <tt>start changes</tt>, <tt>change field</tt>, …,
+<tt>apply</tt>. Having a start call ensures that here are no left over
+changes hanging around, this is an error.  Cancel instead of apply
+is useful when UI cancel is activated so provide it.</p></div>
+<div class="paragraph"><p>The change field call has two options:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+the function specifies the field, eg <tt>change_field(operation *,
+  new_value)</tt>, or
+</p>
+</li>
+<li>
+<p>
+the function specifies the data type, eg <tt>change_string(operation *,
+  enum field, new_value)</tt>
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>The second option has fewer functions, (string, enum/integer, boolean vs
+8-10 fields) and is as ABI conpatible as first if field enum is only
+ever added to.</p></div>
+<div class="paragraph"><p>The first option is shorter to call, and more similar to the GTK
+interface and each function is shorter and independent so choose
+first option.  Getters the same way ie <tt>value_type
+get_fieldname(operation *)</tt>.</p></div>
+<div class="paragraph"><p>In the case of multiple changes during a transaction, most recent
+wins.</p></div>
+<div class="paragraph"><p>Implement by operation structure having a pointer to another
+operation structure created by the <tt>start changes</tt> function. This
+structure holds the changed structure values until <tt>apply</tt>ed.
+<tt>apply</tt> promotes the new structure and frees the old operation
+structure.</p></div>
+<div class="paragraph"><p>Operation needs a <tt>deleted</tt> boolean field so delete is
+<tt>apply</tt>able. It is the caller that decides to clear other fields
+or not.</p></div>
+<div class="paragraph"><p>Each field can have a callback specified to be called on change of that
+field, signature <tt>on_change_func(operation *)</tt>. The pointer points to
+the new operation structure not the old one.  Set by <tt>on_change_func *
+on_change_fieldname(on_change_func *)</tt> returns previous setting.
+Used to trigger the configuration GUI update.</p></div>
+<div class="paragraph"><p>Configure GUI (see below) needs to determine highest priority
+operation based on changes made (but not necessarily applied) so
+make that available as well, returns <tt>current_operations</tt> like list
+but pointing to the new rather than current operations where they
+are relevant, free after use.</p></div>
+<div class="paragraph"><p>Sensitivity flag is needed for internals to set, gives feedback to
+update_menu when Geany/plugins want some special sensitivity
+behaviour.</p></div>
+<div class="paragraph"><p>The operation object has a <tt>do_it</tt> function that performs the operation
+and updates the menu sensitivities during and after the operation.</p></div>
+<h3 id="_build_menu">Build Menu</h3><div style="clear:left"></div>
+<div class="paragraph"><p>The build menu is an array of widgets (actually widget
+pointers), note this includes separator widgets.</p></div>
+<div class="paragraph"><p>Non-separator widgets need the following extra attributes:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+section, item: for fast conversion to the operations list addressing
+</p>
+</li>
+<li>
+<p>
+pointer to process data: process ID, sensitivity group, other data
+</p>
+</li>
+<li>
+<p>
+pointer to operation for this item
+</p>
+</li>
+</ul></div>
+<h3 id="_sensitivity_group">Sensitivity Group</h3><div style="clear:left"></div>
+<div class="paragraph"><p>Linked list linking items of same group so all their sensitivity is
+controlled at once by <tt>set_sensitive</tt> and <tt>set_insensitive</tt> calls
+on the group structure.</p></div>
+<div class="paragraph"><p>For GUI purposes groups can have a name, but do not need to.  The name
+"Parsed" is reserved.</p></div>
+<h3 id="_configure_gui">Configure GUI</h3><div style="clear:left"></div>
+<div class="paragraph"><p>The configure GUI is a dialog with OK, apply, cancel buttons and an</p></div>
+<div class="paragraph"><p>The dialog two panes, left one looks like the menu (as it will be when
+the changes are applied) and is used to select the items to be
+shown in the right pane.  Only one item at a time can be selected
+in the left hand pane and must stay selected, and separators must
+not be selectable.</p></div>
+<h4 id="_left_pane">Left Pane</h4>
+<div class="paragraph"><p>Actually using a menu would give the best appearance, but menus do
+not stay visible and keep the selection active so something else
+must be used.</p></div>
+<div class="paragraph"><p>Use a list with separators shown and single selection only.</p></div>
+<div class="paragraph"><p>Model only needs two fields, a text field for the displayed label and
+an integer which is the index to the build menu array above.</p></div>
+<div class="paragraph"><p>Nothing in this list is editable, the label is updated when a change
+field for a label is called.</p></div>
+<h4 id="_right_pane">Right Pane</h4>
+<div class="paragraph"><p>The right hand pane contains the operations from each source for the
+menu item selected in the left pane and an advanced toggle button
+and (when in advanced) a show all sources toggle button.</p></div>
+<div class="paragraph"><p>Each operation has the fields defined below.</p></div>
+<div class="paragraph"><p>The operations are stacked in the following order (priority by source):</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+internal - insensitive - S
+</p>
+</li>
+<li>
+<p>
+project filetype xxx (if project open) - editable - N
+</p>
+</li>
+<li>
+<p>
+project filetype independent (if project open) - editable -N
+</p>
+</li>
+<li>
+<p>
+user filetype xxx - editable - N
+</p>
+</li>
+<li>
+<p>
+user filetype independent - editable - N
+</p>
+</li>
+<li>
+<p>
+system filetype xxx - insensitive - S
+</p>
+</li>
+<li>
+<p>
+system filetype independent (config file?? or built-in default) -
+insensitive - S
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>The operations are each shown in a frame labelled with the source
+and the list above indicates which are editable and which are shown
+normally ( - N ) and which only when "Show all sources" is selected
+( - S ).  The frame will be different for the source which will be
+used when changes are applied.</p></div>
+<h5 id="_each_operation">Each Operation</h5>
+<div class="paragraph"><p>All operations show a GUI form with the following fields.  The
+fields marked N show in normal and advanced mode, those marked A
+are only shown in advanced mode:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+label - text entry - N
+</p>
+</li>
+<li>
+<p>
+icon - the current icon on a "change" button to call the <tt>select icon</tt>
+dialog - N
+</p>
+</li>
+<li>
+<p>
+internal or external command - combo box, "External" and the internal
+commands - N
+</p>
+</li>
+<li>
+<p>
+command - text entry - N
+</p>
+</li>
+<li>
+<p>
+working Directory - text entry - N
+</p>
+</li>
+<li>
+<p>
+output handling - combo box "Parsed", "Terminal" or "Geany Shell??" - A
+</p>
+</li>
+<li>
+<p>
+stopable - check box - A
+</p>
+</li>
+<li>
+<p>
+stop label - text entry, insensitive if unstopable - A
+</p>
+</li>
+<li>
+<p>
+regular expression source - combo box "Filetype", the source this
+operation is in, "Local" - A
+</p>
+</li>
+<li>
+<p>
+regular expression value - entry, shows/edits the selected source - A
+</p>
+</li>
+<li>
+<p>
+sensitivity group - combo box entry has "Parsed", "Single" and user
+entries - A
+</p>
+</li>
+<li>
+<p>
+clear - button removes the operation & defaults the dialog fields
+</p>
+<div class="dlist"><dl>
+<dt class="hdlist1">
+Notes
+</dt>
+<dd>
+<div class="olist arabic"><ol class="arabic">
+<li>
+<p>
+a better name needed for "Geany Shell" on the combo box
+</p>
+</li>
+<li>
+<p>
+sensitivity group is forced to Parsed and set insensitive if
+parsed output is chosen
+</p>
+</li>
+<li>
+<p>
+A "single" sensitivity group means only this operation is a member
+of an unnamed group
+</p>
+</li>
+<li>
+<p>
+Sensitivity user group names are deleted when no operations are
+members of the group.
+</p>
+</li>
+</ol></div>
+</dd>
+</dl></div>
+</li>
+</ul></div>
+<div class="paragraph"><p>In advanced mode the "show all sources" selection button is also shown.</p></div>
+<h5 id="_select_icon">Select Icon</h5>
+<div class="paragraph"><p>The select icon sub dialog displays the icons from
+<tt>gtk_stock_list_ids</tt> in an iconview and a text entry
+and file browse button calling the file chooser to choose an
+external icon.</p></div>
+<div class="paragraph"><p>This capability might not be in version one since it needs to be able to
+interface to the toolbar to set the icons.</p></div>
+<h3 id="_load_and_store">Load and Store</h3><div style="clear:left"></div>
+<div class="paragraph"><p>Operations are stored in <tt>g_key_files</tt> which are <tt>key=value</tt>
+formatted files with groups of keys separated by <tt>[groupname]</tt>.</p></div>
+<div class="paragraph"><p>Build operations data should be in separate group(s) so as to not
+interfere with other contents of the config file.</p></div>
+<div class="paragraph"><p>The values have to be stored by:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+fieldname
+</p>
+</li>
+<li>
+<p>
+position in menu, ie section number and item number
+</p>
+</li>
+<li>
+<p>
+for the project file only, optional filetype the entry relates to
+</p>
+</li>
+<li>
+<p>
+language the entry relates to (labels are human readable so translatable)
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>Thats five levels of structure, but key files have only two.  So
+allocate levels:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+filetype (or no filetype) to group level, makes the the format of
+each group the same
+</p>
+</li>
+<li>
+<p>
+position and language to the key, locale dependent choice of key is
+a built in keyfile capability
+</p>
+</li>
+<li>
+<p>
+fieldname to the contents of the value, means one value per operation
+so convert to/from string can be part of the operation object.
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>The format will be:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+for the groupname, start with <tt>build-operations</tt> followed by <em>-</em>
+and the filetype if relevant.
+</p>
+</li>
+<li>
+<p>
+for the key, since a key can’t start with a number, <em>s</em>, two digit
+section number, <em>i</em>, two digit item number.  Locale specifier can
+follow.
+</p>
+</li>
+<li>
+<p>
+for the value, since some config files are human edited make the format
+slightly readable as a list of semicolon (;) separated entries consisting
+of, two letter fieldname, <em>:</em>, field value.
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>Fieldnames and value types are:</p></div>
+<div class="tableblock">
+<table rules="all"
+style="margin-left:auto; margin-right:auto;"
+width="70%"
+frame="border"
+cellspacing="0" cellpadding="4">
+<col width="4%" />
+<col width="18%" />
+<col width="77%" />
+<tbody>
+<tr>
+<td align="center" valign="top"><p class="table">ic</p></td>
+<td align="center" valign="top"><p class="table">String</p></td>
+<td align="left" valign="top"><p class="table">Internal command, see below</p></td>
+</tr>
+<tr>
+<td align="center" valign="top"><p class="table">lb</p></td>
+<td align="center" valign="top"><p class="table">String</p></td>
+<td align="left" valign="top"><p class="table">Menu label</p></td>
+</tr>
+<tr>
+<td align="center" valign="top"><p class="table">cm</p></td>
+<td align="center" valign="top"><p class="table">String</p></td>
+<td align="left" valign="top"><p class="table">Command</p></td>
+</tr>
+<tr>
+<td align="center" valign="top"><p class="table">wd</p></td>
+<td align="center" valign="top"><p class="table">string</p></td>
+<td align="left" valign="top"><p class="table">Working directory</p></td>
+</tr>
+<tr>
+<td align="center" valign="top"><p class="table">op</p></td>
+<td align="center" valign="top"><p class="table">Character</p></td>
+<td align="left" valign="top"><p class="table">Output handling, see below</p></td>
+</tr>
+<tr>
+<td align="center" valign="top"><p class="table">st</p></td>
+<td align="center" valign="top"><p class="table">Boolean</p></td>
+<td align="left" valign="top"><p class="table">Stopable</p></td>
+</tr>
+<tr>
+<td align="center" valign="top"><p class="table">sl</p></td>
+<td align="center" valign="top"><p class="table">String</p></td>
+<td align="left" valign="top"><p class="table">Stop label</p></td>
+</tr>
+<tr>
+<td align="center" valign="top"><p class="table">rs</p></td>
+<td align="center" valign="top"><p class="table">Character</p></td>
+<td align="left" valign="top"><p class="table">Regular expression source, see below</p></td>
+</tr>
+<tr>
+<td align="center" valign="top"><p class="table">rv</p></td>
+<td align="center" valign="top"><p class="table">String</p></td>
+<td align="left" valign="top"><p class="table">Local regex value</p></td>
+</tr>
+<tr>
+<td align="center" valign="top"><p class="table">sg</p></td>
+<td align="center" valign="top"><p class="table">Integer or String</p></td>
+<td align="left" valign="top"><p class="table">Sensitivity group, see below</p></td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="paragraph"><p>Boolean data is a string with the first character t or f, the rest is
+ignored, warning and the value false if not t or f.</p></div>
+<div class="paragraph"><p>The following fields are encoded as specified:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+ic: an identifying string, the following are reserved
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+_x - external command
+</p>
+</li>
+<li>
+<p>
+_n - next error
+</p>
+</li>
+<li>
+<p>
+_p - previous error
+</p>
+</li>
+<li>
+<p>
+_c - show config dialog
+</p>
+</li>
+</ul></div>
+</li>
+<li>
+<p>
+op: character, one of
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+p - parsed to build tab of mesage window
+</p>
+</li>
+<li>
+<p>
+t - to the terminal
+</p>
+</li>
+<li>
+<p>
+s - spawned, output to Geany’s terminal
+</p>
+</li>
+</ul></div>
+</li>
+<li>
+<p>
+rs: character one of
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+s - the source regex
+</p>
+</li>
+<li>
+<p>
+f - the filetype regex
+</p>
+</li>
+<li>
+<p>
+l - the local regex in the rv field
+</p>
+</li>
+</ul></div>
+</li>
+<li>
+<p>
+sg: a string if named group, integer if unnamed, <tt>is_ascii_digit</tt> on
+the first character to decide.
+</p>
+</li>
+</ul></div>
+<h4 id="_old_formats">Old Formats</h4>
+<div class="paragraph"><p>The <tt>[build-menu]</tt> format of the current SVN will not be supported,
+if there is sufficient demand a one-time conversion utility can be
+produced.</p></div>
+<div class="paragraph"><p>The <tt>[build-settings]</tt> format of 0.18 will be supported for read
+only.  It will only be used when the appropriate operation has not
+been defined in the new format.  It will be mapped to the current data
+format as follows:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+system and user filetype files:
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+<tt>compiler</tt> - filetype operations section 0, item 0
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+ic = "_x"
+</p>
+</li>
+<li>
+<p>
+lb = "_Compiler"
+</p>
+</li>
+<li>
+<p>
+cm = the value
+</p>
+</li>
+<li>
+<p>
+wd = "%d"
+</p>
+</li>
+<li>
+<p>
+op = <em>p</em>
+</p>
+</li>
+<li>
+<p>
+st = false
+</p>
+</li>
+<li>
+<p>
+rs = <em>f</em>
+</p>
+</li>
+<li>
+<p>
+sg = "Parsed"
+</p>
+</li>
+</ul></div>
+</li>
+<li>
+<p>
+<tt>linker</tt> - filetype operations section 0, item 1
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+ic = "_x"
+</p>
+</li>
+<li>
+<p>
+lb = "_Build"
+</p>
+</li>
+<li>
+<p>
+cm = the value
+</p>
+</li>
+<li>
+<p>
+wd = "%d"
+</p>
+</li>
+<li>
+<p>
+op = <em>p</em>
+</p>
+</li>
+<li>
+<p>
+st = false
+</p>
+</li>
+<li>
+<p>
+rs = <em>f</em>
+</p>
+</li>
+<li>
+<p>
+sg = "Parsed"
+</p>
+</li>
+</ul></div>
+</li>
+<li>
+<p>
+<tt>run_cmd</tt> - filetype operations section 3, item 0
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+ic = "_x"
+</p>
+</li>
+<li>
+<p>
+lb = "_Execute"
+</p>
+</li>
+<li>
+<p>
+cm = the value
+</p>
+</li>
+<li>
+<p>
+wd = "%d"
+</p>
+</li>
+<li>
+<p>
+op = <em>t</em>
+</p>
+</li>
+<li>
+<p>
+st = true
+</p>
+</li>
+<li>
+<p>
+sl = "Stop"
+</p>
+</li>
+<li>
+<p>
+sg = 1
+</p>
+</li>
+</ul></div>
+</li>
+<li>
+<p>
+<tt>error_regex</tt> - filetype regular expression
+</p>
+</li>
+</ul></div>
+</li>
+<li>
+<p>
+user preferences:
+</p>
+<div class="paragraph"><p>If the <tt>make_cmd</tt> key is present the value will be used to create the
+following operations if they don’t already exist in the user filetype
+independent operations:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+Section 1, item 0 - lb = "_Make", cm = value
+</p>
+</li>
+<li>
+<p>
+Section 1, item 1 - lb = "Make Custom _Target", cm = value plus
+  " %c{Enter custom options here, all text will be passed to the Make
+  command}"
+</p>
+</li>
+<li>
+<p>
+Section 1, item 2 - lb = "Make _Object", cm = value plus " %e.o"
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>The rest of the fields have the values:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+ic = "_x"
+</p>
+</li>
+<li>
+<p>
+wd = "%d"
+</p>
+</li>
+<li>
+<p>
+op = <em>p</em>
+</p>
+</li>
+<li>
+<p>
+st = false
+</p>
+</li>
+<li>
+<p>
+rs = <em>s</em>
+</p>
+</li>
+<li>
+<p>
+sg = "Parsed"
+</p>
+</li>
+</ul></div>
+</li>
+<li>
+<p>
+project files:
+</p>
+<div class="paragraph"><p>If the <tt>run_cmd</tt> key is present create the project filetype independent
+section 3, item 0 operation if it doesn’t exist, with the fields:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+ic = "_x"
+</p>
+</li>
+<li>
+<p>
+lb = "_Execute"
+</p>
+</li>
+<li>
+<p>
+cm = the value
+</p>
+</li>
+<li>
+<p>
+wd = "%d"
+</p>
+</li>
+<li>
+<p>
+op = <em>t</em>
+</p>
+</li>
+<li>
+<p>
+st = true
+</p>
+</li>
+<li>
+<p>
+sl = "Stop"
+</p>
+</li>
+<li>
+<p>
+sg = 1
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>The <tt>make_in_base_path</tt> key does not map easily into the new system
+since that assumes each source is independent, but this setting
+exists in the project source and effects commands from the user
+filetype independent source. Changing the working directory of
+another source is hard to undo when the project is closed.</p></div>
+<div class="paragraph"><p>Instead create operations in the project filetype independent source
+which copy the same operation from the user filetype independent
+source for section 1, items 0 to 2 only if they don’t exist in the
+project filetype independent source and the matching user filetype
+independent operation was created from the <tt>make_cmd</tt> key.</p></div>
+</li>
+</ul></div>
+<h3 id="_default_operations">Default Operations</h3><div style="clear:left"></div>
+<div class="paragraph"><p>Makes and internals</p></div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated 2010-02-03 15:43:26 EST
+</div>
+</div>
+</body>
+</html>

Added: branches/bs2/scripts/build_dialog_prototype.py
===================================================================
--- branches/bs2/scripts/build_dialog_prototype.py	                        (rev 0)
+++ branches/bs2/scripts/build_dialog_prototype.py	2010-02-06 10:02:36 UTC (rev 4640)
@@ -0,0 +1,249 @@
+#!/usr/bin/env python
+#
+#       geany.py
+#       
+#       Copyright 2010 Lex Trotman <elextr.at.gmail.dot.com>
+#       
+#       This program 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.
+#       
+#       This program 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 this program; if not, write to the Free Software
+#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+#       MA 02110-1301, USA.
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import pango
+
+def the_end(widget, data=None ):
+	gtk.main_quit()
+
+class data:
+	def __init__(self, name, ft, sens):
+		xp = 6 #padding
+		yp = 6
+		self.frame = gtk.Frame( name + ft )
+		self.tab = gtk.Table(6, 5, False)
+		self.tlab = gtk.Label("Type:")
+		self.tab.attach(self.tlab, 2,3,0,1)
+		self.ic = gtk.combo_box_new_text()
+		self.ic.append_text("External")
+		self.ic.append_text("Next Error")
+		self.ic.append_text("Prev Error")
+		self.ic.append_text("Show Config")
+		self.tab.attach(self.ic, 3,4,0,1)
+		self.llab = gtk.Label("Label:")
+		self.tab.attach(self.llab, 0,1, 0, 1,0,0, xpadding=xp,ypadding=yp)
+		self.lb = gtk.Entry()
+		self.tab.attach(self.lb, 1,2,0,1)
+		self.clab = gtk.Label("Command:")
+		self.tab.attach(self.clab, 0,1, 2,3,0,0, xpadding=xp,ypadding=yp)
+		self.cm = gtk.Entry()
+		self.tab.attach(self.cm, 1,5, 2,3)
+		self.wlab = gtk.Label("Working Dir:")
+		self.tab.attach(self.wlab, 0,1, 3,4,0)
+		self.wd = gtk.Entry()
+		self.tab.attach(self.wd, 1,5, 3,4)
+		self.olab = gtk.Label("Output:")
+		self.tab.attach(self.olab, 0,1, 4,5,0,0)
+		self.op = gtk.combo_box_new_text()
+		self.op.append_text("Parsed")
+		self.op.append_text("Terminal")
+		self.op.append_text("Shell")
+		self.tab.attach(self.op,1,2,4,5)
+		self.rlab = gtk.Label("Regex:")
+		self.tab.attach(self.rlab,2,3,4,5)
+		self.rs = gtk.combo_box_new_text()
+		self.rs.append_text("Local")
+		self.rs.append_text(name)
+		self.rs.append_text("From filetype")
+		self.tab.attach(self.rs,3,4,4,5)
+		self.rv = gtk.Entry()
+		self.tab.attach(self.rv,4,5,4,5)
+		self.st = gtk.CheckButton("Stopable")
+		self.tab.attach(self.st, 2,3,5,6)
+		self.slab = gtk.Label("Stop Label:")
+		self.tab.attach(self.slab,3,4,5,6)
+		self.sl = gtk.Entry()
+		self.tab.attach(self.sl, 4,5,5,6)
+		self.glab = gtk.Label("Group:")
+		self.tab.attach(self.glab, 0,1,5,6,0,0)
+		self.sg = gtk.combo_box_entry_new_text()
+		self.sg.append_text("Parsed")
+		self.sg.append_text("Single")
+		self.tab.attach(self.sg, 1,2,5,6)
+		self.sens = sens
+		if sens :
+			self.clr = gtk.Button(stock=gtk.STOCK_CLEAR)
+			self.tab.attach(self.clr, 4,5,0,1,0,0)
+		else:
+			self.frame.set_sensitive(False)
+		self.frame.add(self.tab)
+	
+	def advanced(self, val):
+		for w in [self.tlab, self.ic, self.olab, self.op, self.rlab, self.rs, self.rv, self.st, self.slab, self.sl, self.glab, self.sg]:
+			if val:
+				w.show_all()
+			else:
+				w.hide_all()
+
+class menu_list:
+	def is_separator(self, model, iter, data=None):
+		return model.get_value(iter,1)<0
+
+	def __init__(self):
+		self.store = gtk.ListStore(str, int)
+		self.store.append(["Compile", 0])
+		self.store.append(["Build", 1])
+		self.store.append(["", 2])
+		self.store.append(["", -1])
+		self.store.append(["Make", 3])
+		self.store.append(["Make Custom Target",4])
+		self.store.append(["Make Object", 5])
+		self.store.append(["", 6])
+		self.store.append(["", -1])
+		self.store.append(["Next Error", 7])
+		self.store.append(["Prev Error", 8])
+		self.store.append(["",-1])
+		self.store.append(["Execute", 9])
+		self.store.append(["",10])
+		self.store.append(["",-1])
+		self.store.append(["Show Configure Dialog", 11])
+		self.view = gtk.TreeView(self.store)
+		self.view.set_row_separator_func(self.is_separator)
+		self.col = gtk.TreeViewColumn("Menu", gtk.CellRendererText(), text=0)
+		self.view.append_column(self.col)
+				
+class dialog:
+	def show_sources(self, widget, data=None):
+		val = widget.get_active()
+		for d in self.d:
+			if not d.sens:
+				if val:
+					d.frame.show_all()
+				else:
+					d.frame.hide_all()
+
+	def advanced(self, widget, data=None):
+		val = widget.get_active()
+		self.shall.set_active(False)
+		self.show_sources(self.shall)
+		if self.proj:
+			self.dpf.advanced(val)
+			self.dp.advanced(val)
+		self.duf.advanced(val)
+		self.du.advanced(val)
+		if val:
+			self.shall.show()
+		else:
+			self.shall.hide()
+	
+	def show_as(self, proj):
+		self.proj = proj
+		if proj:
+			self.dpf.frame.show_all()
+			self.dp.frame.show_all()
+		else:
+			self.dpf.frame.hide_all()
+			self.dp.frame.hide_all()
+		self.advanced(self.adv)
+		ret = self.win.run()
+		self.win.hide()
+		return ret
+
+	def __init__(self):
+		self.proj = True
+		self.win = gtk.Dialog("Build Menu Configuration",
+			None,
+			gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
+			( gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
+			  gtk.STOCK_OK, gtk.RESPONSE_ACCEPT,
+			  gtk.STOCK_APPLY, gtk.RESPONSE_ACCEPT))
+		self.win.set_size_request(800,400)
+		self.panes = gtk.HPaned()
+		self.left = menu_list()
+		self.panes.pack1(self.left.view)
+		self.right = gtk.VBox()
+		self.d = []
+		self.dif = data("Internal Preferences", " for Filetype XXX", False)
+		self.right.pack_start(self.dif.frame,False,False)
+		self.d.append(self.dif)
+		self.di = data("Internal Preferences", " Filetype Independent", False)
+		self.right.pack_start(self.di.frame,False,False)
+		self.d.append(self.di)
+		self.dpf = data("Project Preferences", " for Filetype XXX", True)
+		self.right.pack_start(self.dpf.frame,False,False)
+		self.d.append(self.dpf)
+		self.dp = data("Project Preferences", " Filetype Independent", True)
+		self.right.pack_start(self.dp.frame,False,False)
+		self.d.append(self.dp)
+		self.duf = data("User Preferences", " for Filetype XXX", True)
+		self.right.pack_start(self.duf.frame,False,False)
+		self.d.append(self.duf)
+		l = self.duf.frame.get_label_widget()
+		x = pango.AttrWeight(pango.WEIGHT_BOLD,0,len(l.get_label()))
+		a = pango.AttrList(); a.insert(x)
+		l.set_attributes(a)
+		self.du = data("User Preferences", " Filetype Independent", True)
+		self.right.pack_start(self.du.frame,False,False)
+		self.d.append(self.du)
+		self.dsf = data("System", " for Filetype XXX", False)
+		self.right.pack_start(self.dsf.frame,False,False)
+		self.d.append(self.dsf)
+		self.df = data("System", " Filetype Independent", False)
+		self.right.pack_start(self.df.frame,False,False)
+		self.d.append(self.df)
+		self.swin = gtk.ScrolledWindow()
+		self.swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+		self.swin.add_with_viewport(self.right)
+		self.rt = gtk.VBox()
+		self.rt.pack_start(self.swin)
+		self.ba = gtk.HBox()
+		self.adv = gtk.ToggleButton("Advanced...")
+		self.ba.pack_start(self.adv, False, False)
+		self.adv.connect("toggled", self.advanced)
+		self.shall = gtk.ToggleButton("Show all Sources")
+		self.shall.connect("toggled", self.show_sources)
+		self.ba.pack_end(self.shall, False, False)
+		self.rt.pack_start(self.ba, False, False)
+		self.panes.pack2(self.rt)
+		self.panes.show_all()
+		self.win.vbox.pack_start(self.panes)
+		self.win.connect("destroy", the_end)
+		self.shall.set_active(False)
+		self.adv.set_active(False)
+		self.advanced(self.adv)
+
+the_dialog = None
+
+def show_dialog(widget, val):
+	global the_dialog
+	if the_dialog == None:
+		the_dialog = dialog()
+	print the_dialog.show_as(val)
+
+def main():
+	win = gtk.Window(gtk.WINDOW_TOPLEVEL)
+	vb = gtk.VBox()
+	b1 = gtk.Button("Without a project open")
+	vb.pack_start(b1)
+	b2 = gtk.Button("With a project open")
+	vb.pack_start(b2)
+	b1.connect("clicked", show_dialog, False)
+	b2.connect("clicked", show_dialog, True)
+	win.add(vb)
+	win.connect("destroy", the_end)
+	win.show_all()
+	gtk.main()	
+	return 0
+
+if __name__ == '__main__': main()


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list