Added rst2html code to convert issue text to HTML and display nicely.

This commit is contained in:
Jonathan Bernard 2010-05-27 05:13:29 -05:00
parent 1beb2397e1
commit 5650034cff
22 changed files with 644 additions and 62 deletions

View File

@ -1,35 +0,0 @@
New 'Bugs' created are not correctly categorized.
=================================================
Description
-----------
If the user clicks *New Issue* and does not manually select *Bug* from the drop-down
list, but instead leaves the default *Bug* selected, the actual issue bypasses the
template generation phase and gets its category defaulted to *Task*.
Implementation Notes
--------------------
It looks like this is related to the default value of the category list in the
*New Task* dialog.
Solution
--------
The values from the *NewIssueDialog* are publicly visible via fields on the
model. The view has bound properties to update the model's fields whenever the
appropriate gui field is updated. But when the dialog is shown initially, the
view is reset programatically, not triggering the update to the model values.
In the case of the first new issue since launching the program, the fields on
the model are ``null`` or have their default initialized values. In subsequent
issues, they hold whatever was there before. If the user never changed those
values, they held their old values. The solution was to update the model as
well as the view when showing the dialog.
Resolution
----------
Date Created: 2010-04-20
Date Resolved: 2010-04-20
Delivery: 0022

View File

@ -1,6 +1,5 @@
#utf-8 #utf-8
#Thu May 13 17:04:40 CDT 2010 #Thu May 27 05:01:16 CDT 2010
app.griffon.version=0.3 app.griffon.version=0.3
app.name=pit-swing app.name=pit-swing
app.version=2.3.1 app.version=2.4.0
plugins.fest=0.3

View File

@ -30,6 +30,8 @@ class PITController {
configBinding.templates = model.templates configBinding.templates = model.templates
configBinding.issueListRenderer = model.issueListRenderer configBinding.issueListRenderer = model.issueListRenderer
configBinding.initialRepositories = [] configBinding.initialRepositories = []
configBinding.issueCSS = model.issueCSS
configBinding.PIT_HOME = config.parentFile
def configScript = loader.parseClass(config) def configScript = loader.parseClass(config)
.newInstance(configBinding) .newInstance(configBinding)
@ -55,6 +57,12 @@ class PITController {
loadProject(repo) loadProject(repo)
} }
} }
// open any custom CSS for issue dsiplay
if (configBinding.issueCSS instanceof File)
model.issueCSS = configBinding.issueCSS.text
else
model.issueCSS = configBinding.issueCSS
} }
} }
@ -88,6 +96,7 @@ class PITController {
mainMVC: [model: model, view: view, controller: this], mainMVC: [model: model, view: view, controller: this],
newIssueDialogMVC: model.newIssueDialogMVC, newIssueDialogMVC: model.newIssueDialogMVC,
issueCellRenderer: model.issueListRenderer, issueCellRenderer: model.issueListRenderer,
issueCSS: model.issueCSS,
rootProject: new FileProject(projectDir)) rootProject: new FileProject(projectDir))
newMVC.model.id = projectDir.name newMVC.model.id = projectDir.name

View File

@ -10,13 +10,27 @@ import javax.swing.DefaultListModel
import javax.swing.JOptionPane import javax.swing.JOptionPane
import javax.swing.tree.DefaultMutableTreeNode import javax.swing.tree.DefaultMutableTreeNode
import javax.swing.tree.DefaultTreeModel import javax.swing.tree.DefaultTreeModel
import org.dom4j.Document
import org.dom4j.io.OutputFormat
import org.dom4j.io.XMLWriter
import org.nuiton.jrst.JRSTGenerator
import org.nuiton.jrst.JRSTReader
class ProjectPanelController { class ProjectPanelController {
// these will be injected by Griffon // these will be injected by Griffon
def model def model
def view def view
def jrstReader
def jrstGen
static URL rst2htmlXSL =
ProjectPanelController.class.getResource("/rst2xhtml.xsl")
void mvcGroupInit(Map args) { void mvcGroupInit(Map args) {
jrstReader = new JRSTReader()
jrstGen = new JRSTGenerator()
refreshProject() refreshProject()
} }
@ -27,6 +41,8 @@ class ProjectPanelController {
*/ */
void displayProject(Project project) { void displayProject(Project project) {
view.issueTextArea.text = "" view.issueTextArea.text = ""
view.issueTextDisplay.text = ""
view.issueTextPanelLayout.show(view.issueTextPanel, "display")
if (!project) return if (!project) return
if (!model.projectTableModels[(project.name)]) { if (!model.projectTableModels[(project.name)]) {
@ -57,6 +73,9 @@ class ProjectPanelController {
view.issueTextArea.text = issue.text view.issueTextArea.text = issue.text
view.issueTextArea.caretPosition = 0 view.issueTextArea.caretPosition = 0
view.issueTextDisplay.text = rst2html(issue.text)
view.issueTextDisplay.caretPosition = 0
view.issueTextPanelLayout.show(view.issueTextPanel, "display")
} }
void showProjectPopup(Project project, def x, def y) { void showProjectPopup(Project project, def x, def y) {
@ -164,4 +183,40 @@ class ProjectPanelController {
return view.issueTable.model.issues[view.issueTable. return view.issueTable.model.issues[view.issueTable.
convertRowIndexToModel(view.issueTable.selectedRow)] convertRowIndexToModel(view.issueTable.selectedRow)]
} }
String rst2html(String rst) {
Document doc // memory model of document
StringWriter outString
StringBuilder result = new StringBuilder()
// read the RST in with the RST parser
new StringReader(rst).withReader { doc = jrstReader.read(it) }
// transform to XHTML
doc = jrstGen.transform(doc, rst2htmlXSL)
// write to the StringWriter
outString = new StringWriter()
outString.withWriter { new XMLWriter(it, new OutputFormat("", true)).write(doc) }
// java's embeded html is primitive, we need to massage the results
outString.toString().eachLine { line ->
// remove the XML version and encoding, title element,
// meta elements
if (line =~ /<\?.*\?>/ || line =~ /<meta.*$/ || line =~ /<title.*$/) { return }
// all other elements, remove all class,xmlns attributes
def m = (line =~ /(<\S+)(\s*(class|xmlns)=".*"\s*)*(\/?>.*)/)
if (m) line = m[0][1] + m[0][4]
result.append(line)
// add in the CSS information to the head
if (line =~/<head>/) result.append(model.issueCSS)
}
println result.toString()
return result.toString()
}
} }

View File

@ -18,6 +18,8 @@ class PITModel {
// map of category -> issue template // map of category -> issue template
def templates = [:] def templates = [:]
def issueCSS = getClass().getResource("/default-issue.css").openStream().text
def categoryIcons = [:] def categoryIcons = [:]
def statusIcons = [:] def statusIcons = [:]

View File

@ -18,6 +18,8 @@ class ProjectPanelModel {
@Bindable Project selectedProject = null @Bindable Project selectedProject = null
@Bindable Issue popupIssue = null @Bindable Issue popupIssue = null
String issueCSS = ""
// cache the ListModels // cache the ListModels
def projectTableModels = [:] def projectTableModels = [:]
def issueCellRenderer def issueCellRenderer

View File

@ -0,0 +1,24 @@
<style type="text/css">
body {
font-size: small;
}
h1 {
font-size: medium;
text-decoration: underline;
}
h2 {
font-size: small;
}
h3 {
font-size: small;
font-style: italic;
}
h4 {
font-size: small;
font-weight: normal;
font-style: italic;
}
table,th,td{
border-style: solid;
}
</style>

View File

@ -0,0 +1,495 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/TR/xhtml1/strict">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/document">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="generator" content="JRST http://maven-site.nuiton.org/jrst" />
<title><xsl:value-of select="title"/></title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="comment">
<xsl:comment>
<xsl:text> </xsl:text>
<xsl:apply-templates/>
<xsl:text> </xsl:text>
</xsl:comment>
</xsl:template>
<xsl:template match="title">
<xsl:if test="name(..)='document'">
<h1 class="mainTitle">
<xsl:apply-templates/>
</h1>
</xsl:if>
<xsl:if test="not(name(..)='document')">
<xsl:element name="h{count(ancestor::section) + 1}">
<xsl:attribute name="class">title</xsl:attribute>
<xsl:if test="@refid">
<a class="toc-backref" href="#{@refid}" id="{../@id}"><xsl:apply-templates/></a>
</xsl:if>
<xsl:if test="not(@refid)">
<xsl:apply-templates/>
</xsl:if>
</xsl:element>
</xsl:if>
</xsl:template>
<xsl:template match="subtitle">
<xsl:element name="h2">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<!-- just eat it -->
<xsl:template match="substitution_definition">
</xsl:template>
<xsl:template match="docinfo">
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<xsl:apply-templates/>
</tbody>
</table>
</xsl:template>
<xsl:template match="organization|address|contact|version|revision|status|date|copyright">
<tr>
<th class="docinfo-name">
<xsl:value-of select="name(.)"/> :
</th>
<td class="docinfo-content">
<xsl:apply-templates/>
</td>
</tr>
</xsl:template>
<xsl:template match="author">
<xsl:if test="not(../../authors)">
<tr>
<th class="docinfo-name">
<xsl:value-of select="name(.)"/> :
</th>
<td class="docinfo-content">
<xsl:apply-templates/>
</td>
</tr>
</xsl:if>
<xsl:if test="../../authors">
<xsl:variable name="num" select="position()"/>
<xsl:if test="$num=1">
<tr>
<th class="docinfo-name">
<xsl:value-of select="authors"/>authors :
</th>
<td class="docinfo-content">
<xsl:apply-templates/>
</td>
</tr>
</xsl:if>
<xsl:if test="$num>1">
<tr>
<th>
</th>
<td class="docinfo-content">
<xsl:apply-templates/>
</td>
</tr>
</xsl:if>
</xsl:if>
</xsl:template>
<xsl:template match="transition">
<hr/>
</xsl:template>
<xsl:template match="section">
<a name="{@id}"></a>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="list_item/paragraph[1] | definition_list_item/*/paragraph[1] | field/*/paragraph[1] | option/*/paragraph[1]">
<!--XXX - Unclear how to handle multi-paragraph list items.
| Certainly when they're single paragraphs, we don't want them
| wrapped in a <P> tag. This seems to work okay.
+-->
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="paragraph">
<p><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="reference">
<xsl:if test="@refid">
<a href="{@refuri}#{@refid}" id="{@id}"><xsl:apply-templates/></a>
</xsl:if>
<xsl:if test="not(@refid)">
<a href="{@refuri}" id="{@id}"><xsl:apply-templates/></a>
</xsl:if>
</xsl:template>
<xsl:template match="emphasis">
<em><xsl:apply-templates/></em>
</xsl:template>
<xsl:template match="strong">
<b><xsl:apply-templates/></b>
</xsl:template>
<xsl:template match="literal">
<code><xsl:value-of select="text()"/></code>
</xsl:template>
<xsl:template match="literal_block">
<pre class="literal_block"><xsl:value-of select="text()"/></pre>
</xsl:template>
<xsl:template match="bullet_list">
<ul><xsl:apply-templates/></ul>
</xsl:template>
<xsl:template match="enumerated_list">
<ol>
<xsl:choose>
<xsl:when test="@enumtype='arabic'">
<xsl:attribute name="type">1</xsl:attribute>
</xsl:when>
<xsl:when test="@enumtype='loweralpha'">
<xsl:attribute name="type">a</xsl:attribute>
</xsl:when>
<xsl:when test="@enumtype='upperalpha'">
<xsl:attribute name="type">A</xsl:attribute>
</xsl:when>
<xsl:when test="@enumtype='lowerroman'">
<xsl:attribute name="type">i</xsl:attribute>
</xsl:when>
<xsl:when test="@enumtype='upperroman'">
<xsl:attribute name="type">I</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:copy-of select="@start"/>
<xsl:apply-templates/>
</ol>
</xsl:template>
<xsl:template match="list_item">
<li><xsl:apply-templates/></li>
</xsl:template>
<xsl:template match="field_list">
<div class="field_list"><xsl:apply-templates/></div>
</xsl:template>
<xsl:template match="field">
<xsl:if test="not(../../docinfo)">
<div class="field"><xsl:apply-templates/></div>
</xsl:if>
<xsl:if test="../../docinfo">
<tr>
<th class="docinfo-name">
<xsl:value-of select="field_name/text()"/> :
</th>
<td>
<xsl:apply-templates select="field_body/*"/>
</td>
</tr>
</xsl:if>
</xsl:template>
<xsl:template match="field_name">
<span class="field_name"><xsl:apply-templates/></span>
</xsl:template>
<xsl:template match="field_body">
<span class="field_body"><xsl:apply-templates/></span>
</xsl:template>
<xsl:template match="definition_list">
<dl class="definition_list"><xsl:apply-templates/></dl>
</xsl:template>
<xsl:template match="definition_list_item">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="term">
<dt class="term"><xsl:apply-templates/><xsl:call-template name="classifier"/></dt>
</xsl:template>
<xsl:template name="classifier">
<xsl:for-each select="../classifier">
<span class="classifier"><xsl:apply-templates/></span>
</xsl:for-each>
</xsl:template>
<xsl:template match="classifier">
<!-- do nothing -->
</xsl:template>
<xsl:template match="definition">
<dd class="definition"><xsl:apply-templates/></dd>
</xsl:template>
<xsl:template match="image">
<xsl:choose>
<xsl:when test="(@target) and (@align)">
<div class="align-{@align}" align="{@align}">
<a href="{@target}">
<xsl:call-template name="img" />
</a>
</div>
</xsl:when>
<xsl:when test="@target">
<a href="{@target}">
<xsl:call-template name="img" />
</a>
</xsl:when>
<xsl:when test="@align">
<div class="align-{@align}" align="{@align}">
<xsl:call-template name="img" />
</div>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="img" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="img">
<xsl:element name="img">
<xsl:attribute name="alt"><xsl:value-of select="@alt"/></xsl:attribute>
<xsl:attribute name="src"><xsl:value-of select="@uri"/></xsl:attribute>
<xsl:if test="@width"><xsl:attribute name="width"><xsl:value-of select="@width"/></xsl:attribute></xsl:if>
<xsl:if test="@height"><xsl:attribute name="height"><xsl:value-of select="@height"/></xsl:attribute></xsl:if>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="footer">
<hr/>
<p class="footer"><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="header">
<p class="header"><xsl:apply-templates/></p>
<hr/>
</xsl:template>
<!--
| Table
+-->
<xsl:template match="table">
<table border="1">
<colgroup>
<xsl:apply-templates select="tgroup/colspec"/>
</colgroup>
<xsl:apply-templates select="./tgroup/thead|./tgroup/tbody"/>
</table>
</xsl:template>
<xsl:template match="tgroup/colspec">
<col width="{@colwidth}%"/>
</xsl:template>
<xsl:template match="row">
<tr><xsl:apply-templates/></tr>
</xsl:template>
<xsl:template match="thead">
<thead><xsl:apply-templates/></thead>
</xsl:template>
<xsl:template match="thead/row/entry">
<th>
<xsl:if test="@morecols"><xsl:attribute name="colspan"><xsl:value-of select="@morecols+1"/></xsl:attribute></xsl:if>
<xsl:if test="@morerows"><xsl:attribute name="rowspan"><xsl:value-of select="@morerows+1"/></xsl:attribute></xsl:if>
<xsl:apply-templates/>
</th>
</xsl:template>
<xsl:template match="tbody">
<tbody><xsl:apply-templates/></tbody>
</xsl:template>
<xsl:template match="tbody/row/entry">
<td>
<xsl:if test="@morecols"><xsl:attribute name="colspan"><xsl:value-of select="@morecols+1"/></xsl:attribute></xsl:if>
<xsl:if test="@morerows"><xsl:attribute name="rowspan"><xsl:value-of select="@morerows+1"/></xsl:attribute></xsl:if>
<xsl:apply-templates/>
</td>
</xsl:template>
<xsl:template match="admonition">
<div class="admonition">
<div class="{@class}">
<p class="{title}">
<xsl:apply-templates select="./title"/>
</p>
<p class="body">
<xsl:apply-templates select="child::*[position()>1]"/>
</p>
</div>
</div>
</xsl:template>
<xsl:template match="attention|caution|danger|error|hint|important|note|tip|warning">
<div class="{name(.)}">
<p class="title"><xsl:value-of select="name(.)"/> :</p>
<p class="body">
<xsl:apply-templates/>
</p>
</div>
</xsl:template>
<xsl:template match="block_quote">
<blockquote>
<xsl:if test="./attribution">
<p><xsl:apply-templates select="child::*[position()=1]"/></p>
<p class="attribution">
<xsl:apply-templates select="./attribution"/>
</p>
</xsl:if>
<xsl:if test="not(./attribution)">
<xsl:apply-templates select="child::*"/>
</xsl:if>
</blockquote>
</xsl:template>
<xsl:template match="doctest_block">
<pre class="doctest_block">
<xsl:apply-templates/>
</pre>
</xsl:template>
<xsl:template match="line_block">
<div class="line_block">
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template match="line">
<div class="line">
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template match="sidebar">
<div class="sidebar">
<p class="title">
<xsl:apply-templates select="./title"/>
</p>
<xsl:if test="./subtitle">
<p class="subtitle">
<xsl:apply-templates select="./subtitle"/>
</p>
</xsl:if>
<xsl:choose>
<xsl:when test="./subtitle">
<xsl:apply-templates select="child::*[position()>2]"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="child::*[position()>1]"/>
</xsl:otherwise>
</xsl:choose>
</div>
</xsl:template>
<xsl:template match="topic">
<div class="topic">
<p class="title">
<xsl:apply-templates select="./title"/>
</p>
<xsl:apply-templates select="child::*[position()>1]"/>
</div>
</xsl:template>
<xsl:template match="option_list">
<table class="option_list">
<col class="option" />
<col class="description" />
<tbody valign="top">
<xsl:apply-templates/>
</tbody>
</table>
</xsl:template>
<xsl:template match="option_list_item">
<tr>
<td class="option-group">
<kbd>
<xsl:apply-templates select="./option_group/option"/>
</kbd>
</td>
<td>
<xsl:apply-templates select="./description"/>
</td>
</tr>
</xsl:template>
<xsl:template match="option">
<span class="option">
<xsl:value-of select="option_string/text()"/>
<xsl:value-of select="./option_argument/@delimiter"/>
<xsl:apply-templates select="./option_argument"/>
</span>
</xsl:template>
<xsl:template match="option_argument">
<var>
<xsl:value-of select="text()"/>,
</var>
</xsl:template>
<xsl:template match="footnote">
<table class="footnote" frame="void" id="{@id}" rules="none">
<colgroup>
<col class="label"/>
<col/>
</colgroup>
<tbody valign="top">
<tr>
<td class="label">
<a class="backref" href="#{@backrefs}" name="{id}">
[<xsl:value-of select="label"/>]
</a>
</td>
<td>
<!--
| <xsl:value-of select="child::*[position()>1]"/>
+-->
<xsl:apply-templates select="child::*[position()>1]"/>
</td>
</tr>
</tbody>
</table>
</xsl:template>
<xsl:template match="footnote_reference">
<a class="footnote_reference" href="#{@refid}" id="{@id}" name="{@id}">
[<xsl:value-of select="text()"/>]
</a>
</xsl:template>
</xsl:stylesheet>

View File

@ -57,7 +57,8 @@ Status.values().each {
openDialog = fileChooser(fileSelectionMode: JFileChooser.DIRECTORIES_ONLY) openDialog = fileChooser(fileSelectionMode: JFileChooser.DIRECTORIES_ONLY)
frame = application(title:'Personal Issue Tracker', frame = application(title:'Personal Issue Tracker',
minimumSize: [800, 500], minimumSize: [400, 200],
preferredSize: [800, 500],
pack:true, pack:true,
locationRelativeTo: null, locationRelativeTo: null,
iconImage: imageIcon('/icon64x64.png').image, iconImage: imageIcon('/icon64x64.png').image,

View File

@ -10,6 +10,8 @@ import java.awt.Point
import java.awt.event.MouseEvent import java.awt.event.MouseEvent
import javax.swing.JOptionPane import javax.swing.JOptionPane
import javax.swing.JSplitPane import javax.swing.JSplitPane
import javax.swing.JLabel
import javax.swing.JScrollPane
import javax.swing.JTable import javax.swing.JTable
import javax.swing.JTextField import javax.swing.JTextField
import javax.swing.ListSelectionModel import javax.swing.ListSelectionModel
@ -261,32 +263,60 @@ panel = splitPane(orientation: JSplitPane.HORIZONTAL_SPLIT,
deleteIssueButton = button(deleteIssue, deleteIssueButton = button(deleteIssue,
constraints: gbc(gridx: 2, gridy: 1, anchor: GBC.EAST), constraints: gbc(gridx: 2, gridy: 1, anchor: GBC.EAST),
enabled: bind(source: issueTable.selectionModel, sourceEvent: 'valueChanged', enabled: bind(source: issueTable.selectionModel,
sourceEvent: 'valueChanged',
sourceValue: { !issueTable.selectionModel.isSelectionEmpty() })) sourceValue: { !issueTable.selectionModel.isSelectionEmpty() }))
} }
scrollPane(constraints: "bottom") { scrollPane(constraints: "bottom",
horizontalScrollBarPolicy: JScrollPane.HORIZONTAL_SCROLLBAR_NEVER) {
issueTextPanel = panel {
issueTextPanelLayout = cardLayout()
issueTextArea = textArea( issueTextArea = textArea(
constraints: "editor",
wrapStyleWord: true, wrapStyleWord: true,
lineWrap: bind(source: wordWrapCheckBox, lineWrap: bind(source: wordWrapCheckBox,
sourceProperty: 'selected'), sourceProperty: 'selected'),
editable: bind( source: issueTable.selectionModel, sourceEvent: 'valueChanged', editable: bind( source: issueTable.selectionModel,
sourceValue: { !issueTable.selectionModel.isSelectionEmpty() }), sourceEvent: 'valueChanged',
sourceValue:
{ !issueTable.selectionModel.isSelectionEmpty() }),
font: model.mainMVC.model.issueDetailFont, font: model.mainMVC.model.issueDetailFont,
focusGained: {}, focusGained: {},
focusLost: { focusLost: {
def issue = controller.getSelectedIssue() def issue = controller.getSelectedIssue()
if (issue == null) return if (issue == null) return
if (issueTextArea.text != issue.text) if (issueTextArea.text != issue.text) {
issue.text = issueTextArea.text issue.text = issueTextArea.text
issueTextDisplay.text = controller.rst2html(
issueTextArea.text)
}
issueTextPanelLayout.show(issueTextPanel, "display")
}, },
mouseExited: { mouseExited: {
def issue = controller.getSelectedIssue() def issue = controller.getSelectedIssue()
if (issue == null) return if (issue == null) return
if (issueTextArea.text != issue.text) if (issueTextArea.text != issue.text) {
issue.text = issueTextArea.text issue.text = issueTextArea.text
issueTextDisplay.text = controller.rst2html(
issueTextArea.text)
}
issueTextPanelLayout.show(issueTextPanel, "display")
})
issueTextDisplay = editorPane(contentType: "text/html",
constraints: "display",
editable: false,
preferredSize: [200, 200],
mouseClicked: { evt ->
if (evt.clickCount > 1)
issueTextPanelLayout.show(issueTextPanel, "editor")
}) })
} }
issueTextPanelLayout.show(issueTextPanel, "display")
}
} }
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
pit-swing/lib/pit-2.3.1.jar Normal file

Binary file not shown.

View File

@ -1 +1 @@
application.version=2.3.1 application.version=2.4.0