This commit is contained in:
2016-04-07 20:14:18 -07:00
commit a4cb08398b
170 changed files with 12068 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
/*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package guitartex2;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.BorderLayout;
import java.awt.Panel;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
public class AboutBox extends JFrame implements ActionListener {
private static final long serialVersionUID = 9143994418412032959L;
private final JLabel aboutLabel[];
private static final int labelCount = 6;
private static final int aboutWidth = 280;
private static final int aboutHeight = 230;
private static int aboutTop = 200;
private static int aboutLeft = 350;
private Font titleFont, bodyFont;
private final ResourceBundle resbundle;
public AboutBox() {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
aboutTop = new Double((screenSize.getHeight()/2) - (aboutHeight/2)).intValue();
aboutLeft = new Double((screenSize.getWidth()/2) - (aboutWidth/2)).intValue();
this.setResizable(false);
resbundle = ResourceBundle.getBundle ("GuitarTeX2strings", Locale.getDefault());
SymWindow aSymWindow = new SymWindow();
this.addWindowListener(aSymWindow);
// Initialize useful fonts
titleFont = new Font("Lucida Grande", Font.BOLD, 14);
if (titleFont == null) {
titleFont = new Font("SansSerif", Font.BOLD, 14);
}
bodyFont = new Font("Lucida Grande", Font.PLAIN, 10);
if (bodyFont == null) {
bodyFont = new Font("SansSerif", Font.PLAIN, 10);
}
this.getContentPane().setLayout(new BorderLayout(30, 30));
java.net.URL imgURL = AboutBox.class.getResource("images/gitarre1.jpg");
ImageIcon icon = new ImageIcon(imgURL, "");
aboutLabel = new JLabel[labelCount];
aboutLabel[0] = new JLabel(resbundle.getString("frameConstructor"));
aboutLabel[0].setFont(titleFont);
aboutLabel[1] = new JLabel(resbundle.getString("appVersion"));
aboutLabel[1].setFont(bodyFont);
aboutLabel[2] = new JLabel("");
aboutLabel[3] = new JLabel("JDK " + System.getProperty("java.version"));
aboutLabel[3].setFont(bodyFont);
aboutLabel[4] = new JLabel(resbundle.getString("copyright"));
aboutLabel[4].setFont(bodyFont);
aboutLabel[5] = new JLabel("");
Panel imagePanel = new Panel(new GridLayout(0,1));
imagePanel.add(new JLabel(icon));
Panel textPanel2 = new Panel(new GridLayout(labelCount, 1));
for (int i = 0; i<labelCount; i++) {
aboutLabel[i].setHorizontalAlignment(JLabel.CENTER);
textPanel2.add(aboutLabel[i]);
}
this.getContentPane().add (imagePanel, BorderLayout.PAGE_START);
this.getContentPane().add (textPanel2, BorderLayout.CENTER);
this.pack();
this.setTitle(resbundle.getString("aboutTitle"));
this.setLocation(aboutLeft, aboutTop);
this.setSize(aboutWidth, aboutHeight);
this.setVisible(true);
}
class SymWindow extends java.awt.event.WindowAdapter {
@Override
public void windowClosing(java.awt.event.WindowEvent event) {
setVisible(false);
}
}
@Override
public void actionPerformed(ActionEvent newEvent) {
setVisible(false);
}
}

View File

@@ -0,0 +1,54 @@
/////////////////////////////////////////////////////////
// Bare Bones Browser Launch //
// Version 2.0 (May 26, 2009) //
// By Dem Pilafian //
// Supports: //
// Mac OS X, GNU/Linux, Unix, Windows XP/Vista //
// Example Usage: //
// String url = "http://www.centerkey.com/"; //
// BareBonesBrowserLaunch.openURL(url); //
// Public Domain Software -- Free to Use as You Like //
/////////////////////////////////////////////////////////
package guitartex2;
import java.lang.reflect.Method;
import javax.swing.JOptionPane;
import java.util.Arrays;
public class BareBonesBrowserLaunch {
static final String[] browsers = { "firefox", "opera", "konqueror", "epiphany",
"seamonkey", "galeon", "kazehakase", "mozilla", "netscape" };
public static void openURL(String url) {
String osName = System.getProperty("os.name");
try {
if (osName.startsWith("Mac OS")) {
Class<?> fileMgr = Class.forName("com.apple.eio.FileManager");
Method openURL = fileMgr.getDeclaredMethod("openURL",
new Class[] {String.class});
openURL.invoke(null, new Object[] {url});
}
else if (osName.startsWith("Windows"))
Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
else { //assume Unix or Linux
boolean found = false;
for (String browser : browsers)
if (!found) {
found = Runtime.getRuntime().exec(
new String[] {"which", browser}).waitFor() == 0;
if (found)
Runtime.getRuntime().exec(new String[] {browser, url});
}
if (!found)
throw new Exception(Arrays.toString(browsers));
}
}
catch (Exception e) {
JOptionPane.showMessageDialog(null,
"Error attempting to launch web browser\n" + e.toString());
}
}
}

339
src/guitartex2/COPYRIGHT Normal file
View File

@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -0,0 +1,44 @@
/*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package guitartex2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class CmdExec{
public CmdExec () {
}
public String execute (String cmdline) {
String ausgabe = "";
try {
String line;
Process p = Runtime.getRuntime().exec(cmdline);
try (BufferedReader input = new BufferedReader
(new InputStreamReader(p.getInputStream()))) {
while ((line = input.readLine()) != null) {
ausgabe = ausgabe + line;
}
}
}catch (Exception err) {
InfoBox infoBox = new InfoBox("ERR: " + err);
}
return ausgabe;
}
}

View File

@@ -0,0 +1,509 @@
/*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package guitartex2;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.Properties;
final class Configurations {
private String myName = "GuitarTeX2";
private String propertiesFileName = myName + ".properties";
// get systeminfo
private String osName = System.getProperty( "os.name" );
private String fileSeparator = System.getProperty("file.separator");
private String userPath = System.getProperty("user.home");
private String runPath = System.getProperty("user.dir");
private String pdfViewer = "";
private String tmpDir = "";
private String tmpDirPrefix = "gtxtmp" + fileSeparator;
private Properties mProperties;
private String propertiesFile;
private String confProblems = "";
private GTXConsole mConsole;
// Constructor
public Configurations(GTXConsole consoleBox) {
mProperties = new Properties();
mConsole = consoleBox;
if ( osName.matches("Windows.*")) {
mConsole.addText(osName);
propertiesFile = windowsConfiguration();
}
if ( osName.matches("Linux.*")) {
mConsole.addText("osName");
propertiesFile = linuxConfiguration();
}
if ( osName.matches("Mac OS.*")) {
mConsole.addText(osName);
propertiesFile = macosConfiguration();
}
if ( osName.equals("")) {
mConsole.addText("Unknown OS:" + osName);
propertiesFile = defaultConfiguration();
}
try {
FileInputStream propsFIS;
if ( propertiesFile.equals("")) {
mConsole.addText("taking default config");
propsFIS = new FileInputStream(propertiesFile);
mConsole.addText("loading...");
mProperties.load( propsFIS );
propsFIS.close();
}else{
mConsole.addText("taking prefered config: " + propertiesFile);
propsFIS = new FileInputStream(propertiesFile);
mConsole.addText("checking new entries ...");
// Defaultwerte laden
//File tmpFile = new File(GuitarTeX2.class.getResourceAsStream(propertiesFileName).);
//System.out.println(tmpFile.getAbsoluteFile());
//FileInputStream defaultPropFIS = new FileInputStream(tmpFile);
Properties defProps = new Properties();
//defProps.load(defaultPropFIS);
defProps.load(GuitarTeX2.class.getResourceAsStream(propertiesFileName));
//defaultPropFIS.close();
Enumeration<Object> defElements = defProps.keys();
mProperties.load( propsFIS );
propsFIS.close();
// Auf neue Eintrage pruefen
boolean mustSafe = false;
while (defElements.hasMoreElements()) {
String key = (String)defElements.nextElement();
if ( mProperties.getProperty(key) == null ) {
mProperties.setProperty(key, defProps.getProperty(key));
mustSafe = true;
}
}
if ( mustSafe == true) {
saveSettings();
}
}
}catch (Exception e) {
mConsole.addText("failed to load config file: " + e);
confProblems = confProblems + "Failed to load config file: " + e;
}
}
private String windowsConfiguration() {
String userFileFullPath = userPath + fileSeparator + myName + fileSeparator + propertiesFileName;
String userFileDirectory = userPath + fileSeparator + myName;
boolean userConfigFileResult = checkFile(userFileFullPath);
if ( userConfigFileResult == false ) {
boolean systemConfigFileResult = checkFile(runPath + fileSeparator + myName + fileSeparator + propertiesFileName);
if ( systemConfigFileResult == false ) {
mConsole.addText("creating user config file...");
try {
if ( ! new File(userFileDirectory).exists() ) {
new File(userFileDirectory).mkdir();
}
copyFile(GuitarTeX2.class.getResource(propertiesFileName), new File(userFileFullPath));
return userFileFullPath;
}catch (Exception e) {
mConsole.addText("creating user config file failed: " + e);
return "";
}
}else{
return runPath + fileSeparator + myName + fileSeparator + propertiesFileName;
}
}else{
return userFileFullPath;
}
}
private String linuxConfiguration() {
String userFileFullPath = userPath + fileSeparator + "." + myName + fileSeparator + propertiesFileName;
String userFileDirectory = userPath + fileSeparator + "." + myName;
boolean userConfigFileResult = checkFile(userFileFullPath);
if ( userConfigFileResult == false ) {
boolean systemConfigFileResult = checkFile("/etc/GuitarTeX2" + fileSeparator + propertiesFileName);
if ( systemConfigFileResult == false ) {
mConsole.addText("creating user config file...");
try {
if ( ! new File(userFileDirectory).exists() ) {
new File(userFileDirectory).mkdir();
}
copyFile(GuitarTeX2.class.getResource(propertiesFileName), new File(userFileFullPath));
return userFileFullPath;
}catch (Exception e) {
mConsole.addText("creating user config file failed: " + e);
return "";
}
}else{
return runPath + fileSeparator + myName + fileSeparator + propertiesFileName;
}
}else{
return userFileFullPath;
}
}
private String macosConfiguration() {
String userFileFullPath = userPath + fileSeparator + "." + myName + fileSeparator + propertiesFileName;
String userFileDirectory = userPath + fileSeparator + "." + myName;
boolean userConfigFileResult = checkFile(userFileFullPath);
if ( userConfigFileResult == false ) {
boolean systemConfigFileResult = checkFile("/etc/GuitarTeX2" + fileSeparator + propertiesFileName);
if ( systemConfigFileResult == false ) {
mConsole.addText("creating user config file...");
try {
if ( ! new File(userFileDirectory).exists() ) {
new File(userFileDirectory).mkdir();
}
copyFile(GuitarTeX2.class.getResource(propertiesFileName), new File(userFileFullPath));
return userFileFullPath;
}catch (Exception e) {
mConsole.addText("creating user config file failed: " + e);
return "";
}
}else{
return runPath + fileSeparator + myName + fileSeparator + propertiesFileName;
}
}else{
return userFileFullPath;
}
}
private String defaultConfiguration() {
String userFileFullPath = userPath + fileSeparator + myName + fileSeparator + propertiesFileName;
String userFileDirectory = userPath + fileSeparator + myName;
boolean userConfigFileResult = checkFile(userFileFullPath);
if ( userConfigFileResult == false ) {
mConsole.addText("creating user config file...");
try {
if ( ! new File(userFileDirectory).exists() ) {
new File(userFileDirectory).mkdir();
}
copyFile(GuitarTeX2.class.getResource(propertiesFileName), new File(userFileFullPath));
return userFileFullPath;
}catch (Exception e) {
mConsole.addText("creating user config file failed: " + e);
return "";
}
}else{
return userFileFullPath;
}
}
private void copyFile(URL inURL, File out) throws Exception {
mConsole.addText("CopyFile: " + inURL);
try (InputStream inStream = inURL.openStream(); FileOutputStream fos = new FileOutputStream(out)) {
byte[] buf = new byte[1024];
int i;
while((i=inStream.read(buf))!=-1) {
fos.write(buf, 0, i);
}
}
}
private boolean checkFile(String fileName) {
try {
File myFileName = new File(fileName);
return myFileName.canRead() == true;
}catch (Exception e) {
return false;
}
}
private boolean checkDirectory(String directory) {
try {
File dirName = new File(directory);
if ( dirName.isDirectory() ) {
File testFile = new File(directory+"testFileName.tst");
if ( testFile.createNewFile() ) {
testFile.delete();
return true;
}else{
mConsole.addText("tmpDirectory is not writable");
confProblems = confProblems + "temp directory is not writable!\n";
return false;
}
}else{
mConsole.addText("tmpDirectory doesn't exist");
confProblems = confProblems + "temp directory doesn't exist\n";
return false;
}
}catch (Exception e) {
return false;
}
}
private boolean checkWindowsSettings() {
boolean checkResult;
String path = userPath + fileSeparator + myName + fileSeparator + "tmp" + fileSeparator;
String tmpPath = userPath + fileSeparator + myName + fileSeparator + "tmp" +
fileSeparator + tmpDirPrefix + fileSeparator;
if ( mProperties.getProperty("windowsTmpPath").equals("") ) {
// Create default tmp-Dir
File defTmpDir = new File(tmpPath);
if ( defTmpDir.isDirectory() == false ) {
defTmpDir.mkdirs();
}
mProperties.setProperty("windowsTmpPath", path);
}
checkResult = checkDirectory(mProperties.getProperty("windowsTmpPath"));
checkResult = checkResult & checkFile(mProperties.getProperty("windowsPdfViewer"));
if ( checkResult == false ) {
mConsole.addText("windowsPdfViewer not found");
confProblems = confProblems + "windowsPdfViewer not found\n";
}
pdfViewer = mProperties.getProperty("windowsPdfViewer");
tmpDir = mProperties.getProperty("windowsTmpPath");
return checkResult;
}
private boolean checkLinuxSettings() {
boolean checkResult;
String path = userPath + fileSeparator + "." + myName + fileSeparator + "tmp" + fileSeparator;
String tmpPath = userPath + fileSeparator + "." + myName + fileSeparator + "tmp" +
fileSeparator + tmpDirPrefix + fileSeparator;
if ( mProperties.getProperty("tmpPath").equals("") ) {
// Create default tmp-Dir
File defTmpDir = new File(tmpPath);
if ( defTmpDir.isDirectory() == false ) {
defTmpDir.mkdirs();
}
mProperties.setProperty("tmpPath", path);
}
checkResult = checkDirectory(mProperties.getProperty("tmpPath"));
checkResult = checkResult & checkFile(mProperties.getProperty("linuxPdfViewer"));
if ( checkResult == false ) {
mConsole.addText("linuxPdfViewer not found");
confProblems = confProblems + "linuxPdfViewer not found!\n";
}
pdfViewer = mProperties.getProperty("linuxPdfViewer");
tmpDir = mProperties.getProperty("tmpPath");
return checkResult;
}
private boolean checkMacOSSettings() {
boolean checkResult;
String path = userPath + fileSeparator + "." + myName + fileSeparator + "tmp" + fileSeparator;
String tmpPath = userPath + fileSeparator + "." + myName + fileSeparator + "tmp" + fileSeparator +
tmpDirPrefix + fileSeparator;
if ( mProperties.getProperty("tmpPath").equals("") ) {
// Create default tmp-Dir
File defTmpDir = new File(tmpPath);
if ( defTmpDir.isDirectory() == false ) {
defTmpDir.mkdirs();
}
mProperties.setProperty("tmpPath", path);
}
checkResult = checkDirectory(mProperties.getProperty("tmpPath"));
pdfViewer = "open";
tmpDir = mProperties.getProperty("tmpPath");
return checkResult;
}
private boolean checkOsIndependent() {
boolean checkResult = true;
return checkResult;
}
private void setOsUnknown() {
pdfViewer = "open";
tmpDir = userPath + fileSeparator;
}
public Properties getProperties () {
return mProperties;
}
public String getTmpDir() {
return tmpDir;
}
public void setTmpDir(String mValue) {
if ( osName.equals("Windows XP")) {
mProperties.setProperty("windowsTmpPath", mValue);
}
if ( osName.equals("Linux")) {
mProperties.setProperty("tmpPath", mValue);
}
if ( osName.equals("Mac OS X")) {
mProperties.setProperty("tmpPath", mValue);
}
tmpDir = mValue;
}
public boolean checkConfig() {
boolean testResult = true;
boolean knownSystem = false;
if ( osName.matches("Windows.*")) {
testResult = checkWindowsSettings();
knownSystem = true;
}
if ( osName.matches("Linux.*")) {
testResult = checkLinuxSettings();
knownSystem = true;
}
if ( osName.matches("Mac OS.*")) {
testResult = checkMacOSSettings();
knownSystem = true;
}
if ( knownSystem == false ) {
setOsUnknown();
}
testResult = testResult & checkOsIndependent();
return testResult;
}
public void saveSettings() {
try {
FileOutputStream propsFOS;
mConsole.addText("taking prefered config: " + propertiesFile);
propsFOS = new FileOutputStream(propertiesFile);
mConsole.addText("saving config file ...");
mProperties.store( propsFOS, " ");
propsFOS.close();
}catch (Exception e) {
mConsole.addText("failed to save config file: " + e);
confProblems = confProblems + "failed to save config file: " + e;
}
}
public String getGtxServer() {
return mProperties.getProperty("gtxServer");
}
public void setGtxServer(String mValue) {
mProperties.setProperty("gtxServer", mValue);
}
public int getGtxServerPort() {
return Integer.parseInt(mProperties.getProperty("gtxServerPort"));
}
public void setGtxServerPort(String mValue) {
mProperties.setProperty("gtxServerPort", mValue);
}
public String getPdfViewer() {
return pdfViewer;
}
public void setPdfViewer(String mValue) {
if ( osName.matches("Windows.*")) {
mProperties.setProperty("windowsPdfViewer", mValue);
pdfViewer = mValue;
}
if ( osName.matches("Linux.*")) {
mProperties.setProperty("linuxPdfViewer", mValue);
pdfViewer = mValue;
}
}
public String getConfFile() {
return propertiesFile;
}
public String getLatex() {
return mProperties.getProperty("latex");
}
public void setLatex(String mValue) {
mProperties.setProperty("latex", mValue);
}
public String getXDvi() {
return mProperties.getProperty("xdvi");
}
public void setXDvi(String mValue) {
mProperties.setProperty("xdvi", mValue);
}
public String getPdfLatex() {
return mProperties.getProperty("pdflatex");
}
public void setPdfLatex(String mValue) {
mProperties.setProperty("pdflatex", mValue);
}
public String getConfProblems() {
return confProblems;
}
public String getTmpDirPrefix() {
return tmpDirPrefix;
}
public void setTmpDirPrefix(String mValue) {
tmpDirPrefix = mValue;
}
public String quoteString (String input) {
if ( osName.matches("Windows.*")) {
return "\"" + input + "\"";
}else{
return input;
}
}
public String getFileSeparator() {
return fileSeparator;
}
public String getRunPath() {
return runPath;
}
public String getSongTemplate() {
return runPath + fileSeparator + "examples" + fileSeparator + mProperties.getProperty("exSongFile");
}
public String getBookTemplate() {
return runPath + fileSeparator + "examples" + fileSeparator + mProperties.getProperty("exBookFile");
}
public void loadDefaults() {
try {
Properties defProps;
try (FileInputStream defaultPropFIS = new FileInputStream(propertiesFileName)) {
defProps = new Properties();
defProps.load(defaultPropFIS);
}
mProperties.setProperty("gtxServer", defProps.getProperty("gtxServer"));
mProperties.setProperty("gtxServerPort", defProps.getProperty("gtxServerPort"));
} catch (Exception e) {
InfoBox infoBox = new InfoBox(e + "");
}
/*
mPdfViewerField.setText(myConfiguration.getPdfViewer());
mTmpPathField.setText(myConfiguration.getTmpDir());
*/
}
public GTXConsole getConsole() {
return mConsole;
}
}

View File

@@ -0,0 +1,294 @@
/*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package guitartex2;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
class FileTransfer {
// Debug 0/1
int debug = 0;
// Define commands
//private static String quit = "CMD:123_QUIT_123";
//private static String transfer = "CMD:123_TRANSFER_123";
private static String ok = "CMD:123_OK_123";
private static String failed = "CMD:123_FAILED_123";
// Father ID
int fId;
// Streams
DataInputStream inStream;
DataOutputStream outStream;
// Main - Constructor
public FileTransfer(int id, DataInputStream inputStream, DataOutputStream outputStream) {
fId = id;
inStream = inputStream;
outStream = outputStream;
}
public FileTransfer(int id, int mDebug, DataInputStream inputStream, DataOutputStream outputStream) {
debug = mDebug;
fId = id;
inStream = inputStream;
outStream = outputStream;
}
@SuppressWarnings("UnusedAssignment")
public int sendFile(String myFile) {
RandomAccessFile in;
long length;
String fileLengthResult;
int zipResult = gzipFile(myFile, false);
if (zipResult == 0) {
myFile = myFile + ".gz";
} else {
sendMsg("Filetransfer[" + fId + "]: can't gzip file");
try {
outStream.writeInt(0);
fileLengthResult = inStream.readUTF();
} catch (Exception e) {
sendMsg("Filetransfer[" + fId + "]: stream error" + e);
cleanTmp(myFile);
return 1;
}
cleanTmp(myFile);
return 1;
}
try {
in = new RandomAccessFile(myFile, "r");
length = in.length();
} catch (Exception g) {
sendMsg("Filetransfer[" + fId + "]: can't read file" + g);
try {
outStream.writeInt(0);
fileLengthResult = inStream.readUTF();
} catch (Exception h) {
sendMsg("Filetransfer[" + fId + "]: stream error" + h);
cleanTmp(myFile);
return 1;
}
cleanTmp(myFile);
return 1;
}
if (length > Integer.MAX_VALUE) {
// File is too large
sendMsg("Filetransfer[" + fId + "]: File is too large");
cleanTmp(myFile);
return 1;
} else {
int myFileLength = (int) length;
sendMsg("Filetransfer[" + fId + "]: sending fille length: " + myFileLength);
try {
outStream.writeInt(myFileLength);
fileLengthResult = inStream.readUTF();
} catch (Exception i) {
sendMsg("Filetransfer[" + fId + "]: stream error" + i);
cleanTmp(myFile);
return 1;
}
if (fileLengthResult.equals(ok)) {
try {
sendMsg("Filetransfer[" + fId + "]: send a file...");
byte b;
for (int i = 0; i < myFileLength; i++) {
b = in.readByte();
outStream.writeByte(b);
}
in.close();
File f = new File(myFile);
f.delete();
String fileTransferResult = inStream.readUTF();
if (fileTransferResult.equals(failed)) {
sendMsg("Filetransfer[" + fId + "]: sending file failed: " + fileTransferResult);
cleanTmp(myFile);
return 1;
}
} catch (Exception j) {
sendMsg("Filetransfer[" + fId + "]: stream error" + j);
cleanTmp(myFile);
return 1;
}
} else {
sendMsg("Filetransfer[" + fId + "]: sending file length failed: " + fileLengthResult);
cleanTmp(myFile);
return 1;
}
}
return 0;
}
public int receiveFile(String myFile) {
int fileLength;
RandomAccessFile out;
sendMsg("Filetransfer[" + fId + "]: awaiting filelength ...");
try {
fileLength = inStream.readInt();
} catch (IOException e) {
sendMsg("Filetransfer[" + fId + "]: stream error " + e);
cleanTmp(myFile);
return 1;
}
sendMsg("Filetransfer[" + fId + "]: file length = " + fileLength);
if (fileLength > 0) {
try {
out = new RandomAccessFile(myFile + ".gz", "rw");
} catch (IOException g) {
sendMsg("Filetransfer[" + fId + "]: can't write to a file " + g);
try {
outStream.writeUTF(failed);
} catch (Exception h) {
sendMsg("Filetransfer[" + fId + "]: stream error " + h);
}
cleanTmp(myFile);
return 1;
}
try {
outStream.writeUTF(ok);
} catch (Exception i) {
sendMsg("Filetransfer[" + fId + "]: stream error " + i);
cleanTmp(myFile);
return 1;
}
sendMsg("Filetransfer[" + fId + "]: awaiting file...");
try {
byte b;
for (int i = 0; i < fileLength; i++) {
b = inStream.readByte();
out.write(b);
}
out.close();
} catch (Exception j) {
sendMsg("Filetransfer[" + fId + "]: file transfer failed " + j);
try {
outStream.writeUTF(failed);
} catch (Exception k) {
sendMsg("Filetransfer[" + fId + "]: stream error " + k);
}
cleanTmp(myFile);
return 1;
}
try {
outStream.writeUTF(ok);
int gunzipResult = gunzipFile(myFile + ".gz", true);
if (gunzipResult != 0) {
sendMsg("Filetransfer[" + fId + "]: gunzip failed");
cleanTmp(myFile);
return 1;
}
} catch (Exception l) {
sendMsg("Filetransfer[" + fId + "]: stream error " + l);
cleanTmp(myFile);
return 1;
}
sendMsg("Filetransfer[" + fId + "]: file transfer complete.");
} else {
try {
outStream.writeUTF(failed);
} catch (Exception f) {
sendMsg("Filetransfer[" + fId + "]: file length invalid");
cleanTmp(myFile);
return 1;
}
}
return 0;
}
private int gzipFile(String myFile, boolean delSource) {
int read;
byte[] data = new byte[1024];
sendMsg("Filetransfer[" + fId + "]: gzip file");
try {
File f = new File(myFile);
GZIPOutputStream out;
try (FileInputStream in = new FileInputStream(f)) {
out = new GZIPOutputStream(new FileOutputStream(myFile + ".gz"));
while ((read = in.read(data, 0, 1024)) != -1) {
out.write(data, 0, read);
}
}
out.close();
if (delSource == true) {
f.delete();
}
} catch (Exception e) {
sendMsg("Filetransfer[" + fId + "]: gzipping file failed " + e);
return 1;
}
sendMsg("Filetransfer[" + fId + "]: gzip file");
return 0;
}
private int gunzipFile(String myGZFile, boolean delSource) {
int read;
byte[] data = new byte[1024];
sendMsg("Filetransfer[" + fId + "]: gunzip file");
try {
File f = new File(myGZFile);
FileOutputStream out;
try (GZIPInputStream in = new GZIPInputStream(new FileInputStream(f))) {
String myFile;
if (myGZFile.endsWith(".gz")) {
myFile = myGZFile.substring(0, myGZFile.length() - 3);
} else {
myFile = myGZFile;
} out = new FileOutputStream(myFile);
while ((read = in.read(data, 0, 1024)) != -1) {
out.write(data, 0, read);
}
}
out.close();
if (delSource == true) {
f.delete();
}
} catch (Exception e) {
sendMsg("Filetransfer[" + fId + "]: gunzipping file failed " + e);
return 1;
}
return 0;
}
private void sendMsg(String msg) {
if (debug == 1) {
System.out.println(msg);
}
}
private void cleanTmp(String fileName) {
try {
new File(fileName).delete();
} catch (Exception e) {
sendMsg("can't clean tmp file: " + e);
}
}
}

View File

@@ -0,0 +1,257 @@
/*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package guitartex2;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Locale;
import java.util.ResourceBundle;
public class GTXClient extends Thread{
private static String quit = "CMD:123_QUIT_123";
private static String transfer = "CMD:123_TRANSFER_123";
//private static String ok = "CMD:123_OK_123";
private static String failed = "CMD:123_FAILED_123";
private static String ping = "CMD:123_PING_123";
private static String pong = "CMD:123_PONG_123";
private int id;
private StatusBox myStatusBox;
private String fileName;
private String showPdf;
private boolean hostExist = false;
private ResourceBundle resbundle;
protected Socket serverConn;
DataOutputStream dout;
DataInputStream din;
private GTXConsole myConsole;
private String logCache = "";
// Konstruktor
public GTXClient(String host, int port) {
resbundle = ResourceBundle.getBundle ("GuitarTeX2strings", Locale.getDefault());
try {
logToConsole("Trying to connect to " + host + " " + port);
serverConn = new Socket(host, port);
}catch (UnknownHostException e) {
logToConsole("Bad host name given.");
}catch (IOException e) {
logToConsole("GtxClient: " + e);
}
hostExist = true;
logToConsole("Made server connection");
}
public GTXClient(String host, int port, StatusBox sBox, String file, int myId, String sPdf) {
resbundle = ResourceBundle.getBundle ("GuitarTeX2strings", Locale.getDefault());
try {
logToConsole("Trying to connect to " + host + " " + port);
serverConn = new Socket(host, port);
}catch (UnknownHostException e) {
logToConsole("Bad host name given.");
}catch (IOException e) {
logToConsole("GtxClient: " + e);
}
hostExist = true;
showPdf = sPdf;
id = myId;
myStatusBox = sBox;
fileName = file;
logToConsole("Made server connection");
}
private void logToConsole(String text) {
if ( myConsole == null ) {
if ( logCache.equals("") ) {
logCache = text;
}else{
logCache = logCache + "\n" + text;
}
}else{
if ( ! logCache.equals("") ) {
myConsole.addText(logCache);
logCache = "";
myConsole.addText(text);
}else{
myConsole.addText(text);
}
}
}
void setGTXConsole(GTXConsole mConsole) {
myConsole = mConsole;
if ( ! logCache.equals("") ) {
myConsole.addText(logCache);
logCache = "";
}
}
void forceLogCache() {
if ( myConsole != null ) {
myConsole.addText(logCache);
logCache = null;
}
}
@Override
public void run () {
try {
if ( myStatusBox != null ) {
myStatusBox.setStatus(resbundle.getString("sendTexFile"));
}
dout.writeUTF(transfer);
logToConsole("Client ready for transfer:");
FileTransfer fileTransfer = new FileTransfer(id,0,din, dout);
int texSendResult = fileTransfer.sendFile(fileName);
if ( texSendResult != 0) {
logToConsole("tex file send failed");
}else{
myStatusBox.setStatus(resbundle.getString("wait4PdfFile"));
logToConsole("tex file send.");
}
String texResult = din.readUTF();
if ( texResult.equals(failed)) {
InfoBox infoBox = new InfoBox(resbundle.getString("texFailed"));
logToConsole("texin unsuccessfull");
//myStatusBox.setStatus("FEHLER!");
//myStatusBox.requestFocus();
}else{
myStatusBox.setStatus(resbundle.getString("receivePdfFile"));
String rawFileName = fileName.substring(0, fileName.length()-4);
int pdfResult = fileTransfer.receiveFile(rawFileName + ".pdf");
if ( pdfResult != 0) {
logToConsole("pdf unsuccesfull");
}else{
logToConsole("pdf file received.");
}
myStatusBox.setStatus(resbundle.getString("receiveLogFile"));
int logResult = fileTransfer.receiveFile(rawFileName + ".log");
if ( logResult != 0) {
logToConsole("log unsuccesfull");
}else{
logToConsole("log file received.");
}
myStatusBox.setStatus("try to show PDF file ...");
logToConsole("try to show pdf file");
try{
Runtime.getRuntime().exec(showPdf);
}catch (Exception h) {
logToConsole("ERR: " + h);
}
}
closeConnection();
myStatusBox.setVisible(false);
}catch (Exception e) {
logToConsole("failed texin file: " + e);
}
}
public int openConnection() {
if ( hostExist) {
try {
dout = new DataOutputStream(serverConn.getOutputStream());
din = new DataInputStream(serverConn.getInputStream());
logToConsole("connection open");
return 0;
}catch (Exception e) {
logToConsole("open connection failed: " + e);
return 1;
}
}else{
logToConsole("Host not exists!");
return 1;
}
}
public int closeConnection() {
if ( hostExist ) {
try {
dout.writeUTF(quit);
din.close();
dout.close();
logToConsole("connection closed");
return 0;
}catch (Exception e) {
logToConsole("close connection failed: " + e);
return 1;
}
}else{
logToConsole("Host not exists!");
return 1;
}
}
public int checkServerConnection() {
if ( hostExist ) {
try {
logToConsole("sending ping ...");
dout.writeUTF(ping);
logToConsole("awaiting pong ...");
String pingResult = din.readUTF();
logToConsole(pingResult);
if ( pingResult.equals(pong)) {
logToConsole("pong received.");
return 0;
}else {
logToConsole("server doesn't working.");
return 1;
}
}catch (Exception e) {
logToConsole("ping failed " + e);
return 1;
}
}else{
logToConsole("Host not exists!");
return 1;
}
}
public String sendText(String text) {
String result = "unknown command!";
if ( text.equals("ping") ){
try {
dout.writeUTF(ping);
result = din.readUTF();
if ( result.equals(pong) ) {
result = "pong";
}
dout.writeUTF(quit);
}catch (Exception e) {
logToConsole("Sending failed!");
return "Sending failed!";
}
}
return result;
}
/* public int tex2pdf(String fileName, int id) {
}*/
}

View File

@@ -0,0 +1,217 @@
/*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package guitartex2;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.Panel;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
class GTXConsole extends JFrame implements ActionListener{
private static final long serialVersionUID = -5838495111759011319L;
private Font titleFont, bodyFont;
private static final int statusWidth = 640;
private static final int statusHeight = 480;
private static int statusTop;
private static int statusLeft;
private final ResourceBundle resbundle;
private final JTextArea mShowArea;
//private JTextArea mInputArea;
private final JTextField mInputTextField;
private GTXClient gtxClient;
private Configurations myConf;
private final JButton mInputButton;
private final Action mInputAction;
//public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
public static final String DATE_FORMAT_NOW = "HH:mm:ss";
public GTXConsole() {
resbundle = ResourceBundle.getBundle ("GuitarTeX2strings", Locale.getDefault());
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
statusTop = new Double((screenSize.getHeight()/2) - (statusHeight/2)).intValue();
statusLeft = new Double((screenSize.getWidth()/2) - (statusWidth/2)).intValue();
this.setResizable(false);
SymWindow aSymWindow = new SymWindow();
this.addWindowListener(aSymWindow);
// Initialize useful fonts
titleFont = new Font("Lucida Grande", Font.BOLD, 14);
if (titleFont == null) {
titleFont = new Font("SansSerif", Font.BOLD, 14);
}
bodyFont = new Font("Lucida Grande", Font.PLAIN, 10);
if (bodyFont == null) {
bodyFont = new Font("SansSerif", Font.PLAIN, 10);
}
Panel inputPanel = new Panel(new FlowLayout());
Panel buttonPanel = new Panel(new GridBagLayout());
mShowArea = new JTextArea(resbundle.getString("consoleInitText"));
mShowArea.setEditable(false);
JScrollPane scrollingShowArea = new JScrollPane(mShowArea);
// InputPanel
mInputAction = new buttonActionClass(resbundle.getString("consoleSendButton"));
mInputButton = new JButton(mInputAction);
//mInputButton.setActionCommand("mInputAction");
//mInputArea = new JTextArea();
mInputTextField = new JTextField();
mInputTextField.setColumns(40);
mInputTextField.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), mInputAction);
inputPanel.add(mInputTextField);
inputPanel.add(mInputButton);
mInputButton.setEnabled(false);
mInputAction.setEnabled(false);
// OK - Button
Action mOkAction = new buttonActionClass(resbundle.getString("okButton"));
JButton mOkButton = new JButton(mOkAction);
//mOkButton.setActionCommand("mOkAction");
mOkButton.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), mOkAction);
buttonPanel.add(new JLabel());
buttonPanel.add(mOkButton);
buttonPanel.add(new JLabel());
this.pack();
this.getContentPane().add (scrollingShowArea, BorderLayout.CENTER);
this.getContentPane().add (inputPanel, BorderLayout.PAGE_START);
this.getContentPane().add (buttonPanel, BorderLayout.PAGE_END);
this.setLocation(statusLeft, statusTop);
this.setSize(statusWidth, statusHeight);
this.setTitle(resbundle.getString("consoleTitle"));
this.setVisible(false);
}
public void setGTXClient(Configurations mConf) {
myConf = mConf;
gtxClient = new GTXClient(myConf.getGtxServer(), myConf.getGtxServerPort());
int openResult = gtxClient.openConnection();
if ( openResult == 0 ) {
int connResult = gtxClient.checkServerConnection();
if ( connResult == 0) {
mInputButton.setEnabled(true);
mInputAction.setEnabled(true);
}
}
gtxClient.closeConnection();
}
public class buttonActionClass extends AbstractAction {
private static final long serialVersionUID = 3791659234149686228L;
private final String mAction;
public buttonActionClass(String text) {
super(text);
mAction = text;
}
@Override
public void actionPerformed(ActionEvent e) {
if (mAction.equals(resbundle.getString("consoleSendButton"))) {
// Nachricht anzeigen
addText(mInputTextField.getText());
// Nachricht senden
gtxClient = new GTXClient(myConf.getGtxServer(), myConf.getGtxServerPort());
int openResult = gtxClient.openConnection();
if ( openResult == 0 ) {
String receiveText = gtxClient.sendText(mInputTextField.getText());
addText("Server: " + receiveText);
}
gtxClient.closeConnection();
mInputTextField.setText("");
mInputTextField.requestFocus();
}
// Fenster schliessen
if (mAction.equals(resbundle.getString("okButton"))) {
setVisible(false);
}
}
}
class SymWindow extends java.awt.event.WindowAdapter {
@Override
public void windowClosing(java.awt.event.WindowEvent event) {
setVisible(false);
}
}
@Override
public void actionPerformed(ActionEvent newEvent) {
setVisible(false);
}
public void addText(String text) {
String prefix = this.now() + " # ";
text = text.replaceAll("\n", "\n" + prefix);
mShowArea.setText(mShowArea.getText() + "\n" + prefix + text);
//System.out.println(text);
}
private String now() {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
return sdf.format(cal.getTime());
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
package guitartex2;
class GTXTextConsole {
public GTXTextConsole() {
};
public void addText(String text) {
System.out.println(text);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
latex=/usr/bin/latex
xdvi=/usr/bin/xdvi
pdflatex=/usr/bin/pdflatex
windowsTmpPath=
tmpPath=
windowsPdfViewer=/Programme/Adobe/Reader/AcroRd32.exe
linuxPdfViewer=/usr/bin/acroread
exSongFile=griechischer_wein.gtx
exBookFile=my_first_book.gtb
gtxServer=guitartex2.servebbs.net
gtxServerPort=3121

View File

@@ -0,0 +1,110 @@
/*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package guitartex2;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.Locale;
import java.util.ResourceBundle;
public class GuitarTeX2Convert {
public static void main(String[] args) {
ResourceBundle resbundle = ResourceBundle.getBundle("GuitarTeX2strings", Locale.getDefault());
String help = ""
+ resbundle.getString("appVersion") + "\n"
+ "Usage: \n"
+ " GuitarTeX2Converter -h help (this screen)\n"
+ " GuitarTeX2Converter -f <file.gtx> convert gtx file and print to std out\n"
+ "\n";
if (args.length != 0) {
for (int i = 0; i < args.length; i++) {
if (args[i].equals("--help") || args[i].equals("-help") || args[i].equals("-h") || args[i].equals("--h")) {
System.out.println(help);
System.exit(0);
}
if (args[i].equals("-f") || args[i].equals("--f") || args[i].equals("-file") || args[i].equals("--file")) {
if (i + 1 < args.length) {
String fileName = args[i + 1];
if (!fileName.equals("")) {
File f = new File(fileName);
if (f.canRead()) {
GuitarTeX2Convert guitarTeX2Convert = new GuitarTeX2Convert(f);
} else {
System.out.println("error: can't read file\n");
System.out.println(help);
System.exit(1);
}
} else {
System.out.println(help);
System.exit(1);
}
} else {
System.out.println("error: no file found\n");
System.out.println(help);
System.exit(1);
}
}
}
} else {
System.out.println(help);
System.exit(0);
}
}
public GuitarTeX2Convert(File f) {
String mTextArea = "";
try {
/*InputStreamReader in = new InputStreamReader(fis, Charset.forName("UTF-8"));
while ( in.read() != -1) {
char c = (char)in.read();
mTextArea = mTextArea + c;
}*/
try (FileInputStream fis = new FileInputStream(f); /*InputStreamReader in = new InputStreamReader(fis, Charset.forName("UTF-8"));
while ( in.read() != -1) {
char c = (char)in.read();
mTextArea = mTextArea + c;
}*/ BufferedReader in = new BufferedReader(
new InputStreamReader(new FileInputStream(f), Charset.forName("UTF-8")))) {
boolean eof = false;
while (eof == false) {
String line = in.readLine();
if (line == null) {
eof = true;
} else {
mTextArea = mTextArea + line + "\n";
}
}
}
GTXParser mGTXParser = new GTXParser(mTextArea);
mGTXParser.convertToTeX();
try (OutputStreamWriter out = new OutputStreamWriter(System.out, Charset.forName("UTF-8"))) {
out.write(mGTXParser.getMyTeXFile());
}
} catch (Exception e) {
System.err.println("File input error:" + e);
}
}
}

28
src/guitartex2/INSTALL Normal file
View File

@@ -0,0 +1,28 @@
INSTALL
=======
Anmerkungen
-----------
* Man braucht als Windows/*nix Benutzer einen PDF Betrachter um sich
das Ergebnis anzeigen zu lassen
* Sollte eine Fehlermeldung beim Starten erscheinen, so waehlen Sie
einen installierten PDF Betrachter im Menuepunkt "Preferences".
* Um die Funktion TeX2Pdf nutzen zu koennen braucht man eine Internet-
verbindung. Es muss moeglich sein auf den Port 3121 zugreifen zu koennen.
* Es ist eine beta Version mit einigen bekannten und unbekannten Bugs.
Ich bin fuer jeden Hinweis und Bemerkung dankbar. Bitte nutzen Sie dafuer
die Sourceforge Projektseite http://sourceforge.net/projects/guitartex2
Notes
-----
* Please make sure you have PDF Reader installed on your system.
* You have to set a Reader in a preferences section
* Remote server port is 3121, make sure your Firewall let it pass through
* It's a beta Version with known and unknown bugs. Please report them
using a project page http://sourceforge.net/projects/guitartex2
Have Fun

121
src/guitartex2/InfoBox.java Normal file
View File

@@ -0,0 +1,121 @@
/*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package guitartex2;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.Panel;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
class InfoBox extends JFrame implements ActionListener{
private static final long serialVersionUID = 671314678552270671L;
private Font titleFont, bodyFont;
private static final int statusWidth = 480;
private static final int statusHeight = 200;
private static int statusTop;
private static int statusLeft;
private final ResourceBundle resbundle;
public InfoBox(String myInfo) {
resbundle = ResourceBundle.getBundle ("GuitarTeX2strings", Locale.getDefault());
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
statusTop = new Double((screenSize.getHeight()/2) - (statusHeight/2)).intValue();
statusLeft = new Double((screenSize.getWidth()/2) - (statusWidth/2)).intValue();
this.setResizable(false);
SymWindow aSymWindow = new SymWindow();
this.addWindowListener(aSymWindow);
// Initialize useful fonts
titleFont = new Font("Lucida Grande", Font.BOLD, 14);
if (titleFont == null) {
titleFont = new Font("SansSerif", Font.BOLD, 14);
}
bodyFont = new Font("Lucida Grande", Font.PLAIN, 10);
if (bodyFont == null) {
bodyFont = new Font("SansSerif", Font.PLAIN, 10);
}
Panel buttonPanel = new Panel(new GridBagLayout());
JTextArea mShowArea = new JTextArea(myInfo);
mShowArea.setEditable(false);
JScrollPane scrollingShowArea = new JScrollPane(mShowArea);
Action mOkAction = new buttonActionClass(resbundle.getString("okButton"));
JButton mOkButton = new JButton(mOkAction);
mOkButton.setActionCommand("mOkAction");
buttonPanel.add(new JLabel());
buttonPanel.add(mOkButton);
buttonPanel.add(new JLabel());
this.getContentPane().add (scrollingShowArea, BorderLayout.CENTER);
this.getContentPane().add (buttonPanel, BorderLayout.PAGE_END);
this.pack();
this.setLocation(statusLeft, statusTop);
this.setSize(statusWidth, statusHeight);
this.setVisible(true);
}
public class buttonActionClass extends AbstractAction {
private static final long serialVersionUID = 3791659234149686228L;
public buttonActionClass(String text) {
super(text);
}
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
}
class SymWindow extends java.awt.event.WindowAdapter {
@Override
public void windowClosing(java.awt.event.WindowEvent event) {
setVisible(false);
}
}
@Override
public void actionPerformed(ActionEvent newEvent) {
setVisible(false);
}
}

View File

@@ -0,0 +1,330 @@
/*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package guitartex2;
import java.awt.Toolkit;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
public class PreferencesBox extends JFrame implements ActionListener {
private static final long serialVersionUID = -7086306896538924587L;
private Font titleFont, bodyFont;
private final ResourceBundle resbundle;
private final Configurations myConfiguration;
//private Action mLatexAction, mXDviAction, mPdfLatexAction;
private final Action mPdfViewerAction, mTmpPathAction;
private JTextField mLatexField, mXDviField, mPdfLatexField;
private final JTextField mPdfViewerField;
private final JTextField mTmpPathField;
private final JTextField mGtxServerField, mGtxServerPortField;
private final JButton tex2pdfButton;
private final Action tex2pdfAction;
private final String fileSeparator = System.getProperty("file.separator");
PreferencesBox(Configurations myConf, JButton mTeX2PdfButton, Action mTeX2PdfAction) {
myConfiguration = myConf;
tex2pdfButton = mTeX2PdfButton;
tex2pdfAction = mTeX2PdfAction;
resbundle = ResourceBundle.getBundle("GuitarTeX2strings", Locale.getDefault());
SymWindow aSymWindow = new SymWindow();
this.addWindowListener(aSymWindow);
// Initialize useful fonts
titleFont = new Font("Lucida Grande", Font.BOLD, 14);
if (titleFont == null) {
titleFont = new Font("SansSerif", Font.BOLD, 14);
}
bodyFont = new Font("Lucida Grande", Font.PLAIN, 10);
if (bodyFont == null) {
bodyFont = new Font("SansSerif", Font.PLAIN, 10);
}
// Show local configuration
//Create and populate the panel.
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
//int numPairs = 9;
int numPairs = 6;
int fieldLength = 30;
JPanel p = new JPanel(new SpringLayout());
// External programs
/*
JLabel mLatexLabel = new JLabel(resbundle.getString("mPrefLatex"), JLabel.TRAILING);
p.add(mLatexLabel);
mLatexField = new JTextField(fieldLength);
mLatexField.setText(myConfiguration.getLatex());
mLatexLabel.setLabelFor(mLatexField);
p.add(mLatexField);
mLatexAction = new chooseFileActionClass(resbundle.getString("choose"));
JButton mLatexButton = new JButton(mLatexAction);
mLatexButton.setActionCommand("mLatexAction");
p.add(mLatexButton);
JLabel mXDviLabel = new JLabel(resbundle.getString("mPrefXDvi"), JLabel.TRAILING);
p.add(mXDviLabel);
mXDviField = new JTextField(fieldLength);
mXDviField.setText(myConfiguration.getXDvi());
mXDviLabel.setLabelFor(mXDviField);
p.add(mXDviField);
mXDviAction = new chooseFileActionClass(resbundle.getString("choose"));
JButton mXDviButton = new JButton(mXDviAction);
mXDviButton.setActionCommand("mXDviAction");
p.add(mXDviButton);
JLabel mPdfLatexLabel = new JLabel(resbundle.getString("mPrefPdfLatex"), JLabel.TRAILING);
p.add(mPdfLatexLabel);
mPdfLatexField = new JTextField(fieldLength);
mPdfLatexField.setText(myConfiguration.getPdfLatex());
mPdfLatexLabel.setLabelFor(mPdfLatexField);
p.add(mPdfLatexField);
mPdfLatexAction = new chooseFileActionClass(resbundle.getString("choose"));
JButton mPdfLatexButton = new JButton(mPdfLatexAction);
mPdfLatexButton.setActionCommand("mPdfLatexAction");
p.add(mPdfLatexButton);
*/
JLabel mPdfViewerLabel = new JLabel(resbundle.getString("mPrefPdfViewer"), JLabel.TRAILING);
p.add(mPdfViewerLabel);
mPdfViewerField = new JTextField(fieldLength);
mPdfViewerField.setText(myConfiguration.getPdfViewer());
mPdfViewerLabel.setLabelFor(mPdfViewerField);
p.add(mPdfViewerField);
mPdfViewerAction = new chooseFileActionClass(resbundle.getString("choose"));
JButton mPdfViewerButton = new JButton(mPdfViewerAction);
mPdfViewerButton.setActionCommand("mPdfViewerAction");
p.add(mPdfViewerButton);
// Spaces
p.add(new JLabel());
p.add(new JLabel());
p.add(new JLabel());
// Tmp Path
JLabel mTmpPathLabel = new JLabel(resbundle.getString("mPrefTmpPath"), JLabel.TRAILING);
p.add(mTmpPathLabel);
mTmpPathField = new JTextField(fieldLength);
mTmpPathField.setText(myConfiguration.getTmpDir());
mTmpPathLabel.setLabelFor(mTmpPathField);
p.add(mTmpPathField);
mTmpPathAction = new chooseDirActionClass(resbundle.getString("choose"));
JButton mTmpPathButton = new JButton(mTmpPathAction);
mTmpPathButton.setActionCommand("mTmpPathAction");
p.add(mTmpPathButton);
// Space
p.add(new JLabel());
p.add(new JLabel());
p.add(new JLabel());
// Remote connection
JLabel mGtxServerLabel = new JLabel(resbundle.getString("mPrefGtxServer"), JLabel.TRAILING);
p.add(mGtxServerLabel);
mGtxServerField = new JTextField(fieldLength);
mGtxServerField.setText(myConfiguration.getGtxServer());
mGtxServerLabel.setLabelFor(mGtxServerField);
p.add(mGtxServerField);
p.add(new JLabel());
JLabel mGtxServerPortLabel = new JLabel(resbundle.getString("mPrefGtxServerPort"), JLabel.TRAILING);
p.add(mGtxServerPortLabel);
mGtxServerPortField = new JTextField(fieldLength);
mGtxServerPortField.setText(Integer.toString(myConfiguration.getGtxServerPort()));
mGtxServerPortLabel.setLabelFor(mGtxServerPortField);
p.add(mGtxServerPortField);
p.add(new JLabel());
JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
// Create Buttons
JButton resetButton = new JButton(resbundle.getString("resetButton"));
resetButton.setActionCommand("resetButtonPressed");
resetButton.addActionListener(this);
JButton okButton = new JButton(resbundle.getString("okButton"));
okButton.setActionCommand("okButtonPressed");
okButton.addActionListener(this);
JButton cancelButton = new JButton(resbundle.getString("cancelButton"));
cancelButton.setActionCommand("cancelButtonPressed");
cancelButton.addActionListener(this);
buttonsPanel.add(resetButton);
buttonsPanel.add(cancelButton);
buttonsPanel.add(okButton);
mainPanel.add(p);
mainPanel.add(buttonsPanel);
//Lay out the panel.
SpringUtilities.makeCompactGrid(p,
numPairs, 3, //rows, cols
6, 6, //initX, initY
6, 6); //xPad, yPad
//Create and set up the window.
p.setOpaque(true); //content panes must be opaque
buttonsPanel.setOpaque(true);
mainPanel.setOpaque(true);
this.setResizable(false);
this.getContentPane().add(mainPanel);
this.pack();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int aboutTop = new Double((screenSize.getHeight() / 2) - (this.getHeight() / 2)).intValue();
int aboutLeft = new Double((screenSize.getWidth() / 2) - (this.getWidth() / 2)).intValue();
this.setTitle(resbundle.getString("prefTitle"));
this.setLocation(aboutLeft, aboutTop);
this.setVisible(true);
}
public class chooseFileActionClass extends AbstractAction {
private static final long serialVersionUID = 6483849350866369203L;
public chooseFileActionClass(String text) {
super(text);
}
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser mFileChooser = new JFileChooser(System.getProperty("."));
int retval = mFileChooser.showOpenDialog(PreferencesBox.this);
if (retval == JFileChooser.APPROVE_OPTION) {
String actionCommand = e.getActionCommand();
if (actionCommand.equals("mLatexAction")) {
mLatexField.setText(mFileChooser.getSelectedFile().getAbsolutePath());
}
if (actionCommand.equals("mXDviAction")) {
mXDviField.setText(mFileChooser.getSelectedFile().getAbsolutePath());
}
if (actionCommand.equals("mPdfLatexAction")) {
mPdfLatexField.setText(mFileChooser.getSelectedFile().getAbsolutePath());
}
if (actionCommand.equals("mPdfViewerAction")) {
mPdfViewerField.setText(mFileChooser.getSelectedFile().getAbsolutePath());
}
if (actionCommand.equals("mTmpPathAction")) {
mTmpPathField.setText(mFileChooser.getSelectedFile().getAbsolutePath());
}
}
}
}
public class chooseDirActionClass extends AbstractAction {
private static final long serialVersionUID = 6483849350866369203L;
public chooseDirActionClass(String text) {
super(text);
}
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser mFileChooser = new JFileChooser(System.getProperty("."));
mFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int retval = mFileChooser.showOpenDialog(PreferencesBox.this);
if (retval == JFileChooser.APPROVE_OPTION) {
String actionCommand = e.getActionCommand();
if (actionCommand.equals("mTmpPathAction")) {
mTmpPathField.setText(mFileChooser.getSelectedFile().getAbsolutePath() + fileSeparator);
}
}
}
}
private void setFields() {
//myConfiguration.setLatex(mLatexField.getText());
//myConfiguration.setXDvi(mXDviField.getText());
//myConfiguration.setPdfLatex(mPdfLatexField.getText());
myConfiguration.setPdfViewer(mPdfViewerField.getText());
myConfiguration.setTmpDir(mTmpPathField.getText());
myConfiguration.setGtxServer(mGtxServerField.getText());
myConfiguration.setGtxServerPort(mGtxServerPortField.getText());
}
private void resetFields() {
mPdfViewerField.setText(myConfiguration.getPdfViewer());
mTmpPathField.setText(myConfiguration.getTmpDir());
mGtxServerField.setText(myConfiguration.getGtxServer());
mGtxServerPortField.setText(myConfiguration.getGtxServerPort() + "");
}
class SymWindow extends java.awt.event.WindowAdapter {
@Override
public void windowClosing(java.awt.event.WindowEvent event) {
setVisible(false);
}
}
@Override
public void actionPerformed(ActionEvent newEvent) {
if (newEvent.getActionCommand().equals("resetButtonPressed")) {
myConfiguration.loadDefaults();
resetFields();
}
if (newEvent.getActionCommand().equals("okButtonPressed")) {
setFields();
myConfiguration.saveSettings();
GTXClient gtxClient = new GTXClient(myConfiguration.getGtxServer(), myConfiguration.getGtxServerPort());
gtxClient.setGTXConsole(myConfiguration.getConsole());
int openResult = gtxClient.openConnection();
if (openResult == 0) {
int connResult = gtxClient.checkServerConnection();
if (connResult == 0) {
tex2pdfButton.setEnabled(true);
tex2pdfAction.setEnabled(true);
} else {
tex2pdfButton.setEnabled(false);
tex2pdfAction.setEnabled(false);
}
gtxClient.closeConnection();
} else {
tex2pdfButton.setEnabled(false);
tex2pdfAction.setEnabled(false);
}
setVisible(false);
}
if (newEvent.getActionCommand().equals("cancelButtonPressed")) {
setVisible(false);
}
}
}

View File

@@ -0,0 +1,210 @@
/*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package guitartex2;
import java.awt.Component;
import java.awt.Container;
import javax.swing.Spring;
import javax.swing.SpringLayout;
public class SpringUtilities {
/**
* A debugging utility that prints to stdout the component's
* minimum, preferred, and maximum sizes.
* @param c
*/
public static void printSizes(Component c) {
System.out.println("minimumSize = " + c.getMinimumSize());
System.out.println("preferredSize = " + c.getPreferredSize());
System.out.println("maximumSize = " + c.getMaximumSize());
}
/**
* Aligns the first <code>rows</code> * <code>cols</code>
* components of <code>parent</code> in
* a grid. Each component is as big as the maximum
* preferred width and height of the components.
* The parent is made just big enough to fit them all.
*
* @param parent
* @param rows number of rows
* @param cols number of columns
* @param initialX x location to start the grid at
* @param initialY y location to start the grid at
* @param xPad x padding between cells
* @param yPad y padding between cells
*/
public static void makeGrid(Container parent,
int rows, int cols,
int initialX, int initialY,
int xPad, int yPad) {
SpringLayout layout;
try {
layout = (SpringLayout)parent.getLayout();
} catch (ClassCastException exc) {
System.err.println("The first argument to makeGrid must use SpringLayout.");
return;
}
Spring xPadSpring = Spring.constant(xPad);
Spring yPadSpring = Spring.constant(yPad);
Spring initialXSpring = Spring.constant(initialX);
Spring initialYSpring = Spring.constant(initialY);
int max = rows * cols;
//Calculate Springs that are the max of the width/height so that all
//cells have the same size.
Spring maxWidthSpring = layout.getConstraints(parent.getComponent(0)).
getWidth();
Spring maxHeightSpring = layout.getConstraints(parent.getComponent(0)).
getWidth();
for (int i = 1; i < max; i++) {
SpringLayout.Constraints cons = layout.getConstraints(
parent.getComponent(i));
maxWidthSpring = Spring.max(maxWidthSpring, cons.getWidth());
maxHeightSpring = Spring.max(maxHeightSpring, cons.getHeight());
}
//Apply the new width/height Spring. This forces all the
//components to have the same size.
for (int i = 0; i < max; i++) {
SpringLayout.Constraints cons = layout.getConstraints(
parent.getComponent(i));
cons.setWidth(maxWidthSpring);
cons.setHeight(maxHeightSpring);
}
//Then adjust the x/y constraints of all the cells so that they
//are aligned in a grid.
SpringLayout.Constraints lastCons = null;
SpringLayout.Constraints lastRowCons = null;
for (int i = 0; i < max; i++) {
SpringLayout.Constraints cons = layout.getConstraints(
parent.getComponent(i));
if (i % cols == 0) { //start of new row
lastRowCons = lastCons;
cons.setX(initialXSpring);
} else { //x position depends on previous component
cons.setX(Spring.sum(lastCons.getConstraint(SpringLayout.EAST),
xPadSpring));
}
if (i / cols == 0) { //first row
cons.setY(initialYSpring);
} else { //y position depends on previous row
cons.setY(Spring.sum(lastRowCons.getConstraint(SpringLayout.SOUTH),
yPadSpring));
}
lastCons = cons;
}
//Set the parent's size.
SpringLayout.Constraints pCons = layout.getConstraints(parent);
pCons.setConstraint(SpringLayout.SOUTH,
Spring.sum(
Spring.constant(yPad),
lastCons.getConstraint(SpringLayout.SOUTH)));
pCons.setConstraint(SpringLayout.EAST,
Spring.sum(
Spring.constant(xPad),
lastCons.getConstraint(SpringLayout.EAST)));
}
/* Used by makeCompactGrid. */
private static SpringLayout.Constraints getConstraintsForCell(
int row, int col,
Container parent,
int cols) {
SpringLayout layout = (SpringLayout) parent.getLayout();
Component c = parent.getComponent(row * cols + col);
return layout.getConstraints(c);
}
/**
* Aligns the first <code>rows</code> * <code>cols</code>
* components of <code>parent</code> in
* a grid. Each component in a column is as wide as the maximum
* preferred width of the components in that column;
* height is similarly determined for each row.
* The parent is made just big enough to fit them all.
*
* @param parent
* @param rows number of rows
* @param cols number of columns
* @param initialX x location to start the grid at
* @param initialY y location to start the grid at
* @param xPad x padding between cells
* @param yPad y padding between cells
*/
public static void makeCompactGrid(Container parent,
int rows, int cols,
int initialX, int initialY,
int xPad, int yPad) {
SpringLayout layout;
try {
layout = (SpringLayout)parent.getLayout();
} catch (ClassCastException exc) {
System.err.println("The first argument to makeCompactGrid must use SpringLayout.");
return;
}
//Align all cells in each column and make them the same width.
Spring x = Spring.constant(initialX);
for (int c = 0; c < cols; c++) {
Spring width = Spring.constant(0);
for (int r = 0; r < rows; r++) {
width = Spring.max(width,
getConstraintsForCell(r, c, parent, cols).
getWidth());
}
for (int r = 0; r < rows; r++) {
SpringLayout.Constraints constraints =
getConstraintsForCell(r, c, parent, cols);
constraints.setX(x);
constraints.setWidth(width);
}
x = Spring.sum(x, Spring.sum(width, Spring.constant(xPad)));
}
//Align all cells in each row and make them the same height.
Spring y = Spring.constant(initialY);
for (int r = 0; r < rows; r++) {
Spring height = Spring.constant(0);
for (int c = 0; c < cols; c++) {
height = Spring.max(height,
getConstraintsForCell(r, c, parent, cols).
getHeight());
}
for (int c = 0; c < cols; c++) {
SpringLayout.Constraints constraints =
getConstraintsForCell(r, c, parent, cols);
constraints.setY(y);
constraints.setHeight(height);
}
y = Spring.sum(y, Spring.sum(height, Spring.constant(yPad)));
}
//Set the parent's size.
SpringLayout.Constraints pCons = layout.getConstraints(parent);
pCons.setConstraint(SpringLayout.SOUTH, y);
pCons.setConstraint(SpringLayout.EAST, x);
}
}

View File

@@ -0,0 +1,149 @@
/*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package guitartex2;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.Panel;
import java.awt.Toolkit;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JFrame;
public class StatusBox extends JFrame implements ActionListener {
private static final long serialVersionUID = 8854494445995604753L;
private Font titleFont, bodyFont;
private static int statusWidth = 280;
private static int statusHeight = 100;
private static int statusTop;
private static int statusLeft;
private ResourceBundle resbundle;
private final JLabel myJLStatus;
public StatusBox() {
resbundle = ResourceBundle.getBundle ("GuitarTeX2strings", Locale.getDefault());
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
statusTop = new Double((screenSize.getHeight()/2) - (statusHeight/2)).intValue();
statusLeft = new Double((screenSize.getWidth()/2) - (statusWidth/2)).intValue();
this.setResizable(false);
SymWindow aSymWindow = new SymWindow();
this.addWindowListener(aSymWindow);
// Initialize useful fonts
titleFont = new Font("Lucida Grande", Font.BOLD, 14);
if (titleFont == null) {
titleFont = new Font("SansSerif", Font.BOLD, 14);
}
bodyFont = new Font("Lucida Grande", Font.PLAIN, 10);
if (bodyFont == null) {
bodyFont = new Font("SansSerif", Font.PLAIN, 10);
}
java.net.URL imgURL = StatusBox.class.getResource("images/info.png");
ImageIcon icon = new ImageIcon(imgURL, "");
Panel textPanel = new Panel(new GridBagLayout());
Panel imagePanel = new Panel(new GridBagLayout());
myJLStatus = new JLabel();
imagePanel.add(new JLabel(icon));
textPanel.add(new JLabel());
textPanel.add(myJLStatus);
textPanel.add(new JLabel());
this.getContentPane().add (imagePanel, BorderLayout.PAGE_START);
this.getContentPane().add (textPanel, BorderLayout.CENTER);
this.pack();
this.setTitle(resbundle.getString("statusTitle"));
this.setLocation(statusLeft, statusTop);
this.setSize(statusWidth, statusHeight);
}
public StatusBox(String myStatus) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
statusTop = new Double((screenSize.getHeight()/2) - (statusHeight/2)).intValue();
statusLeft = new Double((screenSize.getWidth()/2) - (statusWidth/2)).intValue();
this.setResizable(false);
SymWindow aSymWindow = new SymWindow();
this.addWindowListener(aSymWindow);
// Initialize useful fonts
titleFont = new Font("Lucida Grande", Font.BOLD, 14);
if (titleFont == null) {
titleFont = new Font("SansSerif", Font.BOLD, 14);
}
bodyFont = new Font("Lucida Grande", Font.PLAIN, 10);
if (bodyFont == null) {
bodyFont = new Font("SansSerif", Font.PLAIN, 10);
}
Panel textPanel = new Panel(new GridBagLayout());
myJLStatus = new JLabel(myStatus);
textPanel.add(new JLabel());
textPanel.add(myJLStatus);
textPanel.add(new JLabel());
this.getContentPane().add (textPanel, BorderLayout.CENTER);
this.pack();
this.setLocation(statusLeft, statusTop);
this.setSize(statusWidth, statusHeight);
this.setVisible(true);
}
public void setStatus(String myStatus) {
myJLStatus.setText(myStatus);
setVisible(true);
}
class SymWindow extends java.awt.event.WindowAdapter {
@Override
public void windowClosing(java.awt.event.WindowEvent event) {
setVisible(false);
}
}
@Override
public void actionPerformed(ActionEvent newEvent) {
setVisible(false);
}
}

View File

@@ -0,0 +1,115 @@
/**
* Original pseudocode : Thomas Weidenfeller Implementation tweaked: Aki
* Nieminen
*
* http://www.unicode.org/unicode/faq/utf_bom.html BOMs: 00 00 FE FF = UTF-32,
* big-endian FF FE 00 00 = UTF-32, little-endian FE FF = UTF-16, big-endian FF
* FE = UTF-16, little-endian EF BB BF = UTF-8
*
* Win2k Notepad: Unicode format = UTF-16LE
**
*/
package guitartex2;
import java.io.*;
/**
* Generic unicode textreader, which will use BOM mark to identify the encoding
* to be used. If BOM is not found then use a given default encoding. System
* default is used if: BOM mark is not found and defaultEnc is NULL
*
* Usage pattern: String defaultEnc = "ISO-8859-1"; // or NULL to use system
* default FileInputStream fis = new FileInputStream(file); Reader in = new
* UnicodeReader(fis, defaultEnc);
*/
public class UnicodeReader extends Reader {
PushbackInputStream internalIn;
InputStreamReader internalIn2 = null;
String defaultEnc;
private static final int BOM_SIZE = 4;
UnicodeReader(InputStream in, String defaultEnc) {
internalIn = new PushbackInputStream(in, BOM_SIZE);
this.defaultEnc = defaultEnc;
}
public String getDefaultEncoding() {
return defaultEnc;
}
public String getEncoding() {
if (internalIn2 == null) {
return null;
}
return internalIn2.getEncoding();
}
/**
* Read-ahead four bytes and check for BOM marks. Extra bytes are unread
* back to the stream, only BOM bytes are skipped.
*
* @throws java.io.IOException
*/
protected void init() throws IOException {
if (internalIn2 != null) {
return;
}
String encoding;
byte bom[] = new byte[BOM_SIZE];
int n, unread;
n = internalIn.read(bom, 0, bom.length);
if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB)
&& (bom[2] == (byte) 0xBF)) {
encoding = "UTF-8";
unread = n - 3;
} else if ((bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) {
encoding = "UTF-16BE";
unread = n - 2;
} else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) {
encoding = "UTF-16LE";
unread = n - 2;
} else if ((bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00)
&& (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) {
encoding = "UTF-32BE";
unread = n - 4;
} else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)
&& (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) {
encoding = "UTF-32LE";
unread = n - 4;
} else {
// Unicode BOM mark not found, unread all bytes
encoding = defaultEnc;
unread = n;
}
// System.out.println("read=" + n + ", unread=" + unread);
if (unread > 0) {
internalIn.unread(bom, (n - unread), unread);
}
// Use given encoding
if (encoding == null) {
internalIn2 = new InputStreamReader(internalIn);
} else {
internalIn2 = new InputStreamReader(internalIn, encoding);
}
}
@Override
public void close() throws IOException {
init();
internalIn2.close();
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
init();
return internalIn2.read(cbuf, off, len);
}
}

View File

@@ -0,0 +1,164 @@
/*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package guitartex2;
//import java.awt.Dimension;
import java.awt.Font;
import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.Panel;
//import java.awt.Toolkit;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JFrame;
public class WarningBox extends JFrame implements ActionListener {
private static final long serialVersionUID = -6792186354255191963L;
private Font titleFont, bodyFont;
private static final int warnWidth = 330;
private static final int warnHeight = 150;
private static int warnTop;
private static int warnLeft;
private final JLabel myJLStatus;
private final String myInfo;
private final Action mOkAction, mInfoAction, mQuitAction;
private final ResourceBundle resbundle;
public WarningBox(String myStatus, String mInfo) {
resbundle = ResourceBundle.getBundle ("GuitarTeX2strings", Locale.getDefault());
myInfo = mInfo;
/* TODO: Bring WarnBox always on top
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
/warnTop = new Double((screenSize.getHeight()/2) - (warnHeight/2)).intValue();
warnLeft = new Double((screenSize.getWidth()/2) - (warnWidth/2)).intValue();
*/
warnTop = 0;
warnLeft = 0;
this.setResizable(false);
SymWindow aSymWindow = new SymWindow();
this.addWindowListener(aSymWindow);
// Initialize useful fonts
titleFont = new Font("Lucida Grande", Font.BOLD, 14);
if (titleFont == null) {
titleFont = new Font("SansSerif", Font.BOLD, 14);
}
bodyFont = new Font("Lucida Grande", Font.PLAIN, 10);
if (bodyFont == null) {
bodyFont = new Font("SansSerif", Font.PLAIN, 10);
}
java.net.URL imgURL = WarningBox.class.getResource("images/info.png");
ImageIcon icon = new ImageIcon(imgURL, "");
Panel imagePanel = new Panel(new GridBagLayout());
Panel textPanel = new Panel(new GridBagLayout());
Panel buttonPanel = new Panel(new GridBagLayout());
myJLStatus = new JLabel(myStatus);
imagePanel.add(new JLabel(icon));
JLabel spaceLabel = new JLabel();
textPanel.add(spaceLabel);
textPanel.add(myJLStatus);
textPanel.add(spaceLabel);
mOkAction = new buttonActionClass(resbundle.getString("okButton"));
JButton mOkButton = new JButton(mOkAction);
mOkButton.setActionCommand("mOkAction");
mInfoAction = new buttonActionClass(resbundle.getString("infoButton"));
JButton mInfoButton = new JButton(mInfoAction);
mInfoButton.setActionCommand("mInfoAction");
mQuitAction = new buttonActionClass(resbundle.getString("quitButton"));
JButton mQuitButton = new JButton(mQuitAction);
mQuitButton.setActionCommand("mQuitAction");
buttonPanel.add(mQuitButton);
buttonPanel.add(mInfoButton);
buttonPanel.add(mOkButton);
this.getContentPane().add (imagePanel, BorderLayout.PAGE_START);
this.getContentPane().add (textPanel, BorderLayout.CENTER);
this.getContentPane().add (buttonPanel, BorderLayout.PAGE_END);
this.pack();
this.setLocation(warnLeft, warnTop);
this.setSize(warnWidth, warnHeight);
this.setTitle(resbundle.getString("warnTitle"));
this.setVisible(true);
//this.setResizable(true);
}
public class buttonActionClass extends AbstractAction {
private static final long serialVersionUID = 3791659234149686228L;
public buttonActionClass(String text) {
super(text);
}
@Override
public void actionPerformed(ActionEvent e) {
String mAction = e.getActionCommand();
if ( mAction.equals("mQuitAction")) {
System.exit(1);
}
if ( mAction.equals("mOkAction")) {
setVisible(false);
setEnabled(false);
}
if ( mAction.equals("mInfoAction")) {
InfoBox infoBox = new InfoBox(myInfo);
}
}
}
class SymWindow extends java.awt.event.WindowAdapter {
@Override
public void windowClosing(java.awt.event.WindowEvent event) {
setVisible(false);
setEnabled(false);
}
}
@Override
public void actionPerformed(ActionEvent newEvent) {
setVisible(false);
setEnabled(false);
}
}

View File

@@ -0,0 +1,461 @@
\documentclass[12pt]{article}
\usepackage[latin1]{inputenc}
\usepackage{amsmath}
\usepackage[german]{babel}
\usepackage{listings}
\usepackage{verbatim}
\usepackage{graphicx}
\newcommand{\ul}{\underline{~}}
\begin{document}
\section{Einf"uhrung}
$GuitarTeX_2$ ist ein Werkzeug f<>r Gitarristen, die gut aussehende Ausdrucke ihrer Musikst<73>cke
oder Liederb<72>cher aus ihren Chord- oder Chordpro-Dateien anfertigen wollen. Es benutzt das
weit verbreitete Chord Format mit einigen Erweiterungen.\\
Es basiert auf einer Idee von Martin Leclerc und Mario Dorion aus Kanada und ihrem Programm
Chord (Version 3.5 von 1993). Um $GuitarTeX_2$ zu nutzen, ben<65>tigen Sie Kenntnisse des Programmes
Chord (wird sp<73>ter erkl<6B>rt). Obwohl das Satzsystem \LaTeX ~von $GuitarTeX_2$ genutzt wird, m<>ssen
sie wenig (oder nichts) <20>ber \LaTeX ~wissen. $GuitarTeX_2$ produziert Postscript- oder PDF-Dateien
automatisch, wenn Sie das m<>chten. Die von $GuitarTeX_2$ unterst<73>tzten Direktiven des Programms
Chord werden erl<72>utert.
\subsection{Eigenschaften}
\begin{itemize}
\item
Grafische Benutzeroberfl<66>che mit integriertem Editor
\item
Druckt gut aussehende Liedbl<62>tter mit Akkorden unter Benutzung von Proportionalschriften
\item
Ausgabeformate \LaTeX, Postscript und PDF
\item
Kompatibel mit ChordPro-Format, Import von ASCII-Dateien
\item
Notensatz mit den \LaTeX-Paketen MusixTeX, MusixLyr und TabDefs
\item
Flexibles Seitenlayout (Gr<47><72>e, R<>nder...)
\item
Benutzerdefinierte Farben f<>r Refrain, Bridge ...
\item
Optionale Ausgabe von Akkordsymbolen am Ende eines St<53>ckes
\item
ASCII-Tabulaturen und eingebaute Funktionen f<>r Gitarrten- und Bass-Tabulaturen
\item
\LaTeX-Kommandos k<>nnen in Chord-Dateien verwendet werden (f<>r Profis)
\end{itemize}
\subsection{Beispiel}
$GuitarTeX_2$ konvertiert eine Datei mit Text und Akkorden im Chord-Format in
eine \LaTeX-Datei. Ein Beispiel f<>r eine Chord-Datei: \\
\\
{\bf\{title:The Manual Song\} \\
\{st:No-one has yet claimed responsibility\} \\
~[D]I print verses [A7]in a [D]row, \\
The next line gets put [A7]down be[D]low, \\
Mumble mumble [A7]rhymes with [D]grow [G] [G\#] [A] \\
Done this verse, now [A7sus4]on we [quietly]go! \\
\\
\{soc\} \\
~[D]This is the [Bm]manual song \\
~[A7]No-one really knows what's [D]goin' on \\
~[D]This is the [F\#m]manual song \\
~[A7]And now the chorus is already [D]gone \\
\{eoc\} \\
\\
~[D]The second verse is [A7]like the [D]first, \\
The music poor, the [A7]verse is [D]worse, \\
I wrote this since [A7]I'd get [D]sued, \\
If I used real songs. [A7]This'll [D]do. \\
\\
\{c:repeat chorus\} } \\
\\
\includegraphics[width=1.1\textwidth]{pics/example1.pdf}
\\
Wenn Sie sich mit \LaTeX ~auskennen, k<>nnen Sie die Ausgabedatei auch manuell ver<65>ndern,
bevor Sie sie in Postscript oder PDF umwandeln. Der Vorteil ist, dass Sie alle M<>glichkeiten
von \LaTeX ~einschlie<69>lich der vielen Zusatzpackete wie graphics oder MusicTeX einsetzen k<>nnen.
\section{Installation}
\subsection{Woher bekomme ich $GuitarTeX_2$}
Die aktuelle Version bekommen Sie immer auf der Download-Seite des $GuitarTeX_2$-Projektes:
http://sourceforge.net/projects/guitartex2.
\subsection{Systemanforderungen}
$GuitarTeX_2$ ist ein Java Programm welches Betriessystemunabh<62>gig entwickelt wurde.
Ben"otigt werden:
\begin{itemize}
\item
Java 1.4 oder h<>her
\item
PDF - Betrachter (z.B. Acrobat Reader, xpdf)
Bei MacOS X braucht man es nicht
\item
Internetverbindung (optinal)
\item
\LaTeX (optional)
\end{itemize}
\subsection{Installation}
Laden sie sich das bin<69>re Paket (GuitarTeX2.jar) herunter. Je nachdem wie sie Ihr
System konfiguriert haben, reicht es darauf zu Doppelklicken oder mit
''java -jar GuitarTeX2.jar'' aus der Kommandozeile zu starten. \\
\\
Es wird beim ersten Starten eine lokale Konfigurationsdatei
angelegt. Diese ist im Homeverzeichnis des Benutzers zu finden. Sie kann nachtr<74>glich
ver<65>ndert werde und wird immer beim starten zuerst ausgelesen.
\section{Der Editor $GuitarTeX_2$}
<Hier kommt bald eine genaue Beschreibung>
\section{Unterst<EFBFBD>tzte Chord-Direktiven}
Direktiven sind Befehle zwischen geschweiften Klammern, die das Aussehen der erzeugten
Ausgabe steuern. Einige h<>ufig ben<65>tigte Direktiven k<>nnen durch eine Abk<62>rzung ersetzt
werden (siehe Beispiele). $GuitarTeX_2$ bringt einige neue Direktiven mit, die das original
Chord Programm nicht kennt.
\subsection{Spezielle Zeichen}
Einige Zeichen haben in GuitarTeX eine besondere Bedeutung:
\begin{itemize}
\item
\# am Anfang einer Zeile markiert einen Kommentar. Die Zeile wird von $GuitarTeX_2$ ignoriert
\item
/ darf nur in Akkorden mit Bass verwendet werden (z.B. A/E)
\end{itemize}
\subsection{Seitenlayout}
Die Direktive geometry bietet flexible M<>glichkeiten, das Layout einer Seite anzupassen.
Sie benutzt das \LaTeX-Paket geometry. Die folgende Beschreibung ist ein (modifizierter)
Teil der Original-Dokumentation.
\\
Das geometry Paket bietet viele automatische Ausrichtungen, so dass nur wenige manuelle
Angaben zum Seitenlayout erforderlich sind. In diesem Fall reicht ein einfaches \\
\\
{\bf\{geometry:a4paper\}} \\
\\
Das Setzen von Seitenr<6E>ndern erfolgt mit \\
\\
{\bf\{geometry:margin=2.5cm\}} \\
\\
wenn alle R<>nder einer Seite 2,5 Zentimeter betragen sollen.
L<>ngenangaben erfolgen in
\begin{itemize}
\item
Zentimeter (cm)
\item
Millimeter (mm)
\item
Inch (in)
\item
Punkt (pt)
\end{itemize}
\subsubsection{Grunds"atzliches}
Das Seitenlayout besteht aus einer einfachen Struktur: Die Seite (paper) enth<74>lt einen
Textk<74>rper (total-body, druckbarer Bereich) und R<>nder. Der Textk<74>rper besteht aus Kopf-
und Fu<46>zeile, dem eigentlichen Text und (optional) den Randbemerkungen. Die vier R<>nder
hei<65>en left-margin, right-margin, top-margin und bottom-margin.\\
\begin{itemize}
\item
paper: total-body (printable area) and margins
\item
total-body: head, body(text area), foot and marginal notes
\item
margins: left-, right-, top- and bottom-margin
\end{itemize}
Jeder Rand wird von der jeweiligen Kante der Seite aus gemessen, z.B. left-margin meint
den Abstand zwischen linker Seitenkante und dem Textk<74>rper. Die Gr<47><72>en von paper, totalbody
und margins stehen in diesen Ralationen:
\begin{itemize}
\item
paperwidth = left + width + right
\item
paperheight = top + height + bottom
\end{itemize}
\subsubsection{Optionen}
Optionen der Direktive geometry: \\
\begin{tabular}{|l|l|}
\textbf{Name} & \textbf{Bedeutung} \\
\hline
landscape & schaltet um auf Querformat \\
portrait & schaltet um auf Hochformat \\
twoside & schaltet auf zweiseitige Ausgabe um. Die linken und rechen R<>nder werden bei geraden
und ungeraden Seiten symmetrisch angeordnet. \\
reversemp & Randbemerkungen erscheinen am linken Rand (statt am rechten Rand) \\
nohead & keine Reservierung von Platz f<>r Kopfzeilen \\
nofoot & keine Reservierung von Platz f<>r Fu<46>zeilen \\
noheadfoot & keine Reservierung von Platz f<>r Kopf- und Fu<46>zeilen \\
a4paper, a5paper & spezifizert die Papiergr<67><72>e, ohne Wert anzugeben \\
paperwidth & Breite des Papiers. paperwidth=$<$paperwidth$>$ \\
paperheight & H<>he des Papiers. paperheight=$<$paperheight$>$ \\
width & Breite des Textk<74>rpers. width=$<$width$>$or totalwidth=$<$width$>$. Diese Angabe
sollte nicht mit der Textbreite (textwidth) verwechselt werden. width enth<74>lt die
Textbreite und die Breite der Randbemerkungen. \\
height & H<>he des Textk<74>rpers (einschlie<69>lich Kopf- und Fu<46>zeile). height=$<$height$>$ \\
left & linker Rand. left=$<$leftmargin$>$ \\
right & rechter Rand. right=$<$rightmargin$>$ \\
top & oberer Rand. top=$<$topmargin$>$ \\
bottom & unterer Rand. bottom=$<$bottommargin$>$ \\
margin & alle R<>nder. margin=$<$margin$>$ \\
textwidth & Breite des Textes. textwidth=$<$width$>$ \\
textheight & H<>he des Textes. textheight=$<$height$>$ \\
marginpar & Breite der Randbemerkungen. marginpar=$<$length$>$ \\
marginparsep & Abstand zwischen Text und Randbemerkungen. marginparsep=$<$length$>$ \\
head & H<>he der Kopfzeile. head=$<$length$>$ \\
headsep & Abstand zwischen Kopfzeile und Text. headsep=$<$length$>$ \\
foot & Abstand zwischen Fu<46>zeile und Text. foot=$<$length$>$ \\
\end{tabular}
\subsubsection{Beispiele}
Setzen Sie die H<>he des Textk<74>rpers auf 10in, den unteren Rand auf 2cm. Der obere
Rand wird automatisch berechnet:\\
\\
{\bf\{geometry:height=10in,bottom=2cm\}} \\
\\
oder: \\
\\
{\bf\{g:height=10in,bottom=2cm\}} \\
\\
oder: \\
\\
{\bf\{geometry:height=10in\} \\
\\
\{g:bottom:=2cm\}} \\
\\
Setzen Sie den linken, rechten und oberen Rand auf 3cm, 2cm und 2.5in.
Es wird keine Kopfzeile ben<65>tigt. \\
\\
{\bf\{geometry:left=3cm,right=2cm, nohead,top=2.5in\}} \\
\\
oder: \\
\\
{\bf\{geometry:left=3cm\} \\
\{geometry:right=2cm\} \\
\{geometry:nohead\} \\
\{geometry:top=2.5in\}} \\
\\
oder : \\
\\
{\bf\{g:left=3cm,right=2cm\} \\
\{g:nohead, top=2.5in\}} \\
\\
und so weiter ... \\
<09>ndern Sie die Breite der Randbemerkungen auf 3cm \\
\\
{\bf\{geometry:marginpar=3cm\} \\
\{geometry:marginpar=3cm, reversemp\}} \\
\\
l<>sst die Randbemerkungen am linken Rand ausgeben.\\
Verwenden sie A5-Papier im Querformat: \\
\\
{\bf\{geometry:a5paper, landscape\}} \\
\subsection{Dokumentenstrukur}
\subsubsection{title}
Der Titel eines St<53>ckes wird durch die Direktive title markiert. Der
Titel wird zentriert mit einer vergr<67><72>erten Schrift ausgegeben.
In Dokumenten mit mehreren St<53>cken verursacht title einen Seitenumbruch. \\
Beispiel:\\
\\
{\bf\{title:Go Down Moses\} \\
\{t:Go Down Moses\}} \\
\subsubsection{subtitle}
Die Direktive \textbf{subtitle} dient zur Darstellung zus<75>tzlicher
Informationen, wie z.B. Interpret oder Komponist. \\
Beispiel: \\
\\
{\bf\{subtitle:written by John Lennon / Paul McCartney\} \\
\{st:written by John Lennon / Paul McCartney\}} \\
\subsubsection{bridge}
Eine Bridge wird mit \{bridge\} oder \{sob\} (start of bridge) am Anfang,
und \{/bridge\} oder \{eob\} (end of bridge) am Ende markiert. Die Bridge
wird auf Farbdruckern in blau ausgegeben. Die Farbe kann mit der Direktive
color\underline{~}bridge angepasst werden (siehe Abschnitt namens color\underline{~}xxx).\\
Beispiel: \\
\\
{\bf \{bridge\} \\
I want her [Ab]everywhere [Fm] \\
And if [Bbm]she's beside me [C7]I know I need [Fm]never care \\
~[Bb]But to love her [C7]is to meet her \\
\{/bridge\}} \\
\subsubsection{chorus}
Ein Refrain wird mit \{chorus\} oder \{soc\} (start of chorus) am Anfang und mit \{/chorus\}
oder \{eoc\} (end of chorus) am Ende markiert. Der Refrain wird auf Farbdruckern in rot
ausgegeben. Die Farbe kann mit der Direktive color\underline{~}chorus angepasst werden
(siehe Abschnitt namens color\underline{~}xxx).\\
Beispiel: \\
\\
{\bf\{chorus\} \\
Oh, I get [C]by with a little [G]help from my [D]friends \\
Mm, I get [C]high with a little [G]help from my [D]friends \\
Oh, I'm gonna [C]try with a little [G]help from my [D]friends \\
\{/chorus\}} \\
\subsubsection{instr}
Ein Instrumental-Teil wird mit \{instr\} oder \{soi\} (start of instrumental) am Anfang
und \{/instr\} oder \{eoi\} (end of instrumental) am Ende markiert. Der Instrumental-Teil
wird auf Farbdruckern in grau ausgegeben. Die Farbe kann mit der Direktive
color\underline{~}instr angepasst werden (siehe Abschnitt namens color\underline{~}xxx).
\subsubsection{np}
np steht f<>r eine ''neue Seite'' und erzeugt einen Seitenumbruch.\\
Beispiel: \\
{\bf\{np\}} \\
\subsubsection{tab}
Tabulaturen werden mit \{tab\} oder \{sot\} (start of tablature) am Anfang und \{/tab\}
oder \{eot\} (end of tablature) am Ende markiert. Tabulaturen werden auf Farbdruckern
in gr<67>n ausgegeben. Die Farbe kann mit der Direktive color\underline{~}tab directive
angepasst werden (siehe Abschnitt namens color\underline{~}xxx). Tabulaturen werden
in einer nichtproportionalen Schriftart ausgegeben.\\
Beispiel: \\
\includegraphics[width=15cm]{pics/tabs1.pdf}
\subsection{Fonts}
Die Direktiven zur Beeinflussung der Schriftart und -farbe k<>nnen irgendwo in Ihrer Datei
stehen. Trotzdem ist es hilfreich sie am Anfang zu platzieren. Die angegebenen Werte
gelten f<>r das ganze Dokument.
\subsubsection{font\underline{~}size}
\LaTeX ~kennt drei Schriftgr<67><72>en 10pt, 11pt and 12pt. GuitarTeX nutzt normalerweise
11pt (Titel und Untertitel werden automatisch vergr<67><72>ert). Wenn Sie z.B. 12pt
verwenden wollen, schreiben Sie:\\
\\
{\bf\{font\underline{~}size:12\}} \\
\\
Achtung: schreiben Sie nicht 12pt statt 12!\\
\subsubsection{color\underline{~}xxx}
Mit den folgenden Direktiven k<>nnen Sie die Textfarbe f<>r Refrain, Bridge,
Instrumental-Teil Tabulaturen und zweite Stimme anpassen. F<>r die zweite Stimme
k<>nnen Sie auch die Hintergrundfarbe <20>ndern, so dass Sie z.B. wei<65>e Schrift auf einem
farbigen Hintergrund verwenden k<>nnen. Das erleichtert den S<>ngern hoffentlich
die Orientierung bei mehreren Textzeilen. \\
Die Direktiven hei<65>en: \\
\begin{itemize}
\item
color\underline{~}chorus
\item
color\underline{~}bridge
\item
color\underline{~}instr
\item
color\underline{~}tab
\item
color\underline{~}second
\item
color\underline{~}second\underline{~}back
\end{itemize}
Als Parameter wird eine durch Kommas getrennte Liste von Werten zwischen null und
eins, die die Farben rot, gr<67>n und blau repr<70>sentieren.\\
Beispiel: \\
\\
{\bf\{color\underline{~}chorus:.5,.5,1\}}
\subsection{Gitarren- und Bass-Tabulaturen}
$GuitarTeX_2$ kennt zwei neue Direktiven zur Darstellung von Tabulaturen:
\begin{itemize}
\item
\{guitartab: \} f<>r Gitarren-Tabulaturen
\item
\{basstab: \} f<>r Bass-Tabulaturen
\end{itemize}
Jede guitartab oder basstab Direktive stellt eine Zeile mit sechs bzw vier Linien dar.
Sie k<>nnen mit \{guitartab: \} oder \{basstab: \} auch leere Tabulaturen erzeugen.
Setzen Sie eine Leerzeile vor die Direktive, damit die Tabulatur am linken Rand beginnt.\\
Die Klammern k<>nnen enthalten:
\begin{itemize}
\item
normaler Text, der unterhalb der Tabulatur ausgegeben wird
\item
Noten im Format [string;fret], z.B. [2;5] f<>r 5. Bund auf der A-Saite
\item
Taktstriche (durch das Zeichen $|$ dargestellt)
\item
Zus<75>tzlicher Leerraum mit ''\ul{}''
\end{itemize}
Beispiel: leere Gitarrentabulatur \\
\\
{\bf\{guitartab:\}} \\
\\
Beispiel: Eine Bass-Tabulatur mit Text \\
\\
{\bf\{basstab:some text\}} \\
\\
Beispiel: Noten, Taktstriche und Leerraum \\
\\
{\bf\{guitartab:[2;3][3;0][3;2][3;3]$|$[4;0]\ul\ul[4;2]\ul\ul[5;0]\ul\ul[5;1]$|$\}} \\
\\
Beispiel: Text unter den Noten anordnen \\
\\
{\bf\{guitartab:[2;3]do [3;0]re [3;2]mi [3;3]fa $|$[4;0]so [4;2]la [5;0]si [5;1]do$|$\}} \\
\\
Beispiel: Eine einfache Bass-Tabulatur \\
\\
{\bf\{basstab:[2;5][2;5]$|$[2;5][2;5]$|$[3;5][3;5]$|$[2;5][2;5]$|$[3;7][3;7]$|$[3;5][3;5]$|$[2;5]\}} \\
\\
Beispiel: Akkorde \\
\\
{\bf\{guitartab:[2;3]\&[3;5]\&[4;5]C (power chord) $|$[2;3]\&[3;2]\&[4;0]\&[5;1]C chord\}} \\
\subsection{N"utzliches}
\subsubsection{define}
Mit der Direktive define k<>nnen Sie ein Akkord-Symbol am Ende eines St<53>ckes erstellen.
Die Direktive kann irgendwo im St<53>ck platziert sein.\\
define verf<72>gt <20>ber acht Parameter:\\
\begin{itemize}
\item
den Akkordnamen
\item
die Nummer des ersten Bundes
\item
sechs Nummern f<>r die sechs Saiten (ein x bedeutet, dass die Saite nicht gespielt wird)
\end{itemize}
Beispiel:\\
\\
{\bf\{define:A 1 x n 2 2 2 n\} \\
\{define:Cm 3 x 1 3 3 2 1\} \\
\{define:Gm/Bb 4 3 2 2 1 x x\}} \\
\subsubsection{comment}
Die Direktive comment f<>gt einen Text ein, der nicht zum eigentlichen St<53>ck geh<65>rt. \\
Beispiel: \\
\\
{\bf\{comment: repeat chorus\} \\
\{c: repeat chorus\}} \\
\subsubsection{margin}
Die Direktive margin erzeugt eine Randbemerkung. Diese k<>nnen z.B. dazu genutzt werden,
Hinweise f<>r den Musiker einzuf<75>gen.\\
Beispiel: \\
\\
{\bf\{margin:Fade Out\} \\
\{m:Fade Out\}} \\
\subsubsection{second}
In einigen St<53>cken hat die zweite Stimme nicht nur eine andere Melodie, sondern auch
einen anderen oder versetzt gesungenen Text. Bekannte Beispiele sind "California Dreaming"
von The Mamas And The Papas und "Help" von den Beatles. Wenn Sie die zweite Stimme mit
der Direktive second markieren erscheint sie in wei<65>er Schrift auf grauem Hintergrund.
Wegen der proportionalen Schrift m<>ssen Sie ein wenig experimentieren, um die korrekte
Ausrichtung zwischen erster und zweiter Stimme zu erhalten.\\
Beispiel: \\
\\
{\bf[G] When I was younger so much [Hm]younger than today \\
\{second:When when I was young\} \\
~[Em] I never needed anybody's [C]help in [F]any [G]way \\
\{second:I never need help in any way\} \\
~[G]But now these days are gone and I'm [Bm]not so self assured \\
\{second:Now these days are gone\} \\
~[Em] Now I find I've changed my mind, \\
\{second:And now I find\} \\
I've [C]opened [F]up the [G]doors \\
\{second:I've opened up the doors\}} \\
\section{\LaTeX-Kommandos und Pakete verwenden}
\subsection{\LaTeX-Kommandos}
Wie in der Einf<6E>hrung erw<72>hnt, brauchen Sie nichts <20>ber \LaTeX ~zu wissen, um $GuitarTeX_2$
zu nutzen. Wenn Sie sich mit \LaTeX ~auskennen, k<>nnen Sie dessen M<>glichkeiten nutzen,
um Ihre Ergebnisse weiter zu verbessern. Alle Zeilen, die mit einem Backslash beginnen,
werden in die erzeute \LaTeX-Datei <20>bernommen. Sie k<>nnen das einfach mit einem Kommando
wie diesem testen: \\
\\
{\bf$\backslash$marginpar\{test\}} \\
\\
Das Ergebnis ist eine Randbemerkung mit dem Wort ''test''.
Die \LaTeX-Kommandos werden an der Stelle ausgef<65>hrt, an der sie in der Datei vorkommen.
Manche Kommandos m<>ssen allerdings in der sog. Pr<50>ambel der \LaTeX-Datei erscheinen.
Das geschieht mit der Direktive preamble:\\
\\
{\bf\{preamble:$\backslash$usepackage(fancyheadings)\}}\\
\\
Die Direktive preamble kann irgendwo im Dokument stehen. Die enthaltenen Kommandos
erscheinen in der \LaTeX-Pr<50>ambel in der Reihenfolge, in der sie in der Chord-Datei stehen.
\end{document}

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 892 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1017 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 821 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 909 B