Adding gwt QR Code generator, and appspot configuration files.

git-svn-id: https://zxing.googlecode.com/svn/trunk@788 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
leppoc 2008-12-16 23:08:42 +00:00
parent 30f8fa2736
commit 7352202c90
27 changed files with 2051 additions and 0 deletions

View file

@ -0,0 +1,16 @@
application: zxing
version: 1
runtime: python
api_version: 1
handlers:
- url: /generator
script: redirect.py
- url: (.*)/
static_files: static\1/index.html
upload: static/index.html
- url: /
static_dir: static

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="gwt-user.jar"/>
<classpathentry kind="lib" path="gwt.jar"/>
<classpathentry kind="var" path="JUNIT_HOME/junit.jar"/>
<classpathentry kind="lib" path="libs/gwt-incubator.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8" ?>
<projectDescription>
<name>BarcodeGenerator</name>
<comment>BarcodeGenerator project</comment>
<projects/>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments/>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<linkedResources>
<link>
<name>gwt-user.jar</name>
<type>1</type>
<locationURI>GWT_HOME/gwt-user.jar</locationURI>
</link>
<link>
<name>gwt.jar</name>
<type>1</type>
<locationURI>GWT_JAR</locationURI>
</link>
</linkedResources>
</projectDescription>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/BarcodeGenerator/gwt.jar"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="1"/>
</listAttribute>
<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER&quot; javaProject=&quot;BarcodeGenerator&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/BarcodeGenerator/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;BarcodeGenerator&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/BarcodeGenerator/gwt.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.launching.macosx.MacOSXType/JVM 1.5.0 (MacOS X Default)"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.GWTShell"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out www com.google.zxing.web.generator.Generator/Generator.html"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="BarcodeGenerator"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx256M -XstartOnFirstThread"/>
</launchConfiguration>

View file

@ -0,0 +1,11 @@
To develop with Eclipse.
Before importing the project, you need to define some variables.
- In Eclipse Preferences, go to General->Workspace->Linked Resources.
- Click New and add the 2 following variables:
- GWT_HOME that point to the directory containing gwt-user.jar
- GWT_JAR that point to the gwt-dev-XXX.jar file directly. (XXX will be linux, mac, etc)
- then you can import the project by File->Import...->Existing project into workspace.

Binary file not shown.

View file

@ -0,0 +1,18 @@
<module>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
<!-- Inherit the default GWT style sheet. -->
<inherits name='com.google.gwt.user.theme.standard.Standard'/>
<!-- Other module inherits -->
<inherits name="com.google.gwt.widgetideas.WidgetIdeas" />
<inherits name='com.google.gwt.libideas.LibIdeas' />
<!-- Specify the app entry point class. -->
<entry-point class='com.google.zxing.web.generator.client.Generator'/>
<!-- Specify the application specific style sheet. -->
<stylesheet src='Generator.css' />
<stylesheet src="DatePickerDemo.css" />
</module>

View file

@ -0,0 +1,273 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.widgetideas.client.event.ChangeEvent;
import com.google.gwt.widgetideas.client.event.ChangeHandler;
import com.google.gwt.widgetideas.datepicker.client.DateBox;
import com.google.gwt.widgetideas.datepicker.client.TimePicker;
import com.google.zxing.web.generator.client.TimeZoneList.TimeZoneInfo;
import java.util.Date;
/**
* A Generator for calendar events. Output is in VCal format.
*
* @author Yohann Coppel
*/
public class CalendarEventGenerator implements GeneratorSource {
public final static String[] FULL_DAY_ONLY_IDS = { "fullDayOnlyInfo1",
"fullDayOnlyInfo2", "fullDayOnlyInfo3", "fullDayOnlyInfo4" };
private final static long ONE_HOUR = 60 * 60 * 1000;
Grid table = null;
TextBox eventName = new TextBox();
CheckBox fullDay = new CheckBox();
DateBox datePicker1 = new DateBox();
DateBox datePicker2 = new DateBox();
TimePicker timePicker1 = new TimePicker(new Date(), DateTimeFormat
.getFormat("a"), DateTimeFormat.getFormat("hh"), DateTimeFormat
.getFormat("mm"), null);
TimePicker timePicker2 = new TimePicker(new Date(), DateTimeFormat
.getFormat("a"), DateTimeFormat.getFormat("hh"), DateTimeFormat
.getFormat("mm"), null);
CheckBox summerTime = new CheckBox();
ListBox timeZones = new ListBox();
Date timePicker1PreviousDate = null;
public CalendarEventGenerator(final ChangeListener listener) {
eventName.addStyleName(StylesDefs.INPUT_FIELD_REQUIRED);
eventName.addChangeListener(listener);
datePicker1.setAnimationEnabled(true);
datePicker2.setAnimationEnabled(true);
timePicker2
.setDateTime(addMilliseconds(timePicker1.getDateTime(), ONE_HOUR));
timePicker1PreviousDate = timePicker1.getDateTime();
buildTimeZoneList();
timeZones.setSelectedIndex(25);
timePicker1.addChangeHandler(new ChangeHandler<Date>() {
public void onChange(ChangeEvent<Date> event) {
Date time = timePicker1PreviousDate;
Date time1 = timePicker1.getDateTime();
Date time2 = timePicker2.getDateTime();
if (time2.after(time)) {
// keep the same time difference if the interval is valid.
long diff = timeDifference(time, time2);
timePicker2.setDateTime(addMilliseconds(time1, diff));
} else {
// otherwise erase the end date and set it to startdate + one hour.
timePicker2.setDateTime(addMilliseconds(time, ONE_HOUR));
}
// no need to call onChange for timePicker1, since it will be called
// for timePicker2 when changes are made.
// listener.onChange(timePicker1);
timePicker1PreviousDate = time1;
}
});
timePicker2.addChangeHandler(new ChangeHandler<Date>() {
public void onChange(ChangeEvent<Date> event) {
listener.onChange(timePicker2);
}
});
}
private void buildTimeZoneList() {
for (TimeZoneInfo info : TimeZoneList.TIMEZONES) {
timeZones.addItem(info.GMTRelative + " " + info.abreviation, ""
+ info.gmtDiff);
}
}
public String getName() {
return "Calendar event";
}
public Grid getWidget() {
if (table != null) {
return table;
}
datePicker1.getDatePicker().setSelectedDate(new Date());
datePicker2.getDatePicker().setSelectedDate(new Date());
table = new Grid(8, 2);
table.setText(0, 0, "All day event");
table.setWidget(0, 1, fullDay);
table.setText(1, 0, "Event title");
table.setWidget(1, 1, eventName);
table.setText(2, 0, "Start date");
table.setWidget(2, 1, datePicker1);
table.setText(3, 0, "Time");
table.setWidget(3, 1, timePicker1);
table.setText(4, 0, "End date");
table.setWidget(4, 1, datePicker2);
table.setText(5, 0, "Time");
table.setWidget(5, 1, timePicker2);
table.setText(6, 0, "Time zone");
table.setWidget(6, 1, timeZones);
table.setText(7, 0, "Daylight savings");
table.setWidget(7, 1, summerTime);
table.getRowFormatter().getElement(3).setId(FULL_DAY_ONLY_IDS[0]);
table.getRowFormatter().getElement(5).setId(FULL_DAY_ONLY_IDS[1]);
table.getRowFormatter().getElement(6).setId(FULL_DAY_ONLY_IDS[2]);
table.getRowFormatter().getElement(7).setId(FULL_DAY_ONLY_IDS[3]);
fullDay.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
CheckBox cb = (CheckBox) sender;
setFullDay(cb.isChecked());
}
});
return table;
}
private void setFullDay(boolean fullDay) {
for (String s : FULL_DAY_ONLY_IDS) {
Element element = DOM.getElementById(s);
String style = "";
if (fullDay) {
style = "none";
}
DOM.setStyleAttribute(element, "display", style);
}
}
public String getText() throws GeneratorException {
String eventName = getEventNameField();
String dates = getDateTimeFields();
String output = "";
output += "BEGIN:VEVENT\n";
output += eventName;
output += dates;
output += "END:VEVENT\n";
return output;
}
private String getEventNameField() throws GeneratorException {
String inputName = eventName.getText();
if (inputName.length() < 1) {
throw new GeneratorException("Event name must be at least 1 character.");
}
if (inputName.contains("\n")) {
throw new GeneratorException(
"Event name should not contain \\n characters.");
}
return "SUMMARY:" + inputName + "\n";
}
private String getDateTimeFields() throws GeneratorException {
if (fullDay.isChecked()) {
return getFullDayDateFields();
}
return getDateTimeValues();
}
private String getFullDayDateFields() throws GeneratorException {
Date date1 = datePicker1.getDatePicker().getSelectedDate();
Date date2 = datePicker2.getDatePicker().getSelectedDate();
if (null == date1 || null == date2) {
throw new GeneratorException("Start and end dates must be set.");
}
if (date1.after(date2)) {
throw new GeneratorException("Ending date is after starting date.");
}
DateTimeFormat isoFormatter = DateTimeFormat.getFormat("yyyyMMdd");
String output = "";
output += "DTSTART:" + isoFormatter.format(date1) + "\n";
output += "DTEND:" + isoFormatter.format(date2) + "\n";
return output;
}
private String getDateTimeValues() throws GeneratorException {
Date date1 = datePicker1.getDatePicker().getSelectedDate();
Date date2 = datePicker2.getDatePicker().getSelectedDate();
Date time1 = timePicker1.getDateTime();
Date time2 = timePicker2.getDateTime();
if (null == date1 || null == date2 || null == time1 || null == time2) {
throw new GeneratorException("Start and end dates/times must be set.");
}
String timezoneDelta = timeZones.getValue(timeZones.getSelectedIndex());
long diffTimeZone = Long.parseLong(timezoneDelta);
if (summerTime.isChecked()) {
diffTimeZone += ONE_HOUR;
}
Date dateTime1 = addMilliseconds(mergeDateAndTime(date1, time1),
-diffTimeZone);
Date dateTime2 = addMilliseconds(mergeDateAndTime(date2, time2),
-diffTimeZone);
if (dateTime1.after(dateTime2)) {
throw new GeneratorException("Ending date is after starting date.");
}
DateTimeFormat isoFormatter = DateTimeFormat
.getFormat("yyyyMMdd'T'kkmmss'Z'");
String output = "";
output += "DTSTART:" + isoFormatter.format(dateTime1) + "\n";
output += "DTEND:" + isoFormatter.format(dateTime2) + "\n";
return output;
}
private Date mergeDateAndTime(Date date, Date time) {
// Is that the only ugly way to do with GWT ? given that we don't
// have java.util.Calendar for instance
DateTimeFormat extractDate = DateTimeFormat.getFormat("yyyyMMdd");
DateTimeFormat extractTime = DateTimeFormat.getFormat("kkmm");
DateTimeFormat merger = DateTimeFormat.getFormat("yyyyMMddkkmmss");
String d = extractDate.format(date);
String t = extractTime.format(time) + "00";
return merger.parse(d + t);
}
public void validate(Widget widget) throws GeneratorException {
if (widget == eventName)
getEventNameField();
if (widget == datePicker1 || widget == timePicker1 || widget == datePicker2
|| widget == timePicker2)
getDateTimeFields();
}
private static Date addMilliseconds(Date time1, long milliseconds) {
return new Date(time1.getTime() + milliseconds);
}
private static long timeDifference(Date time1, Date time2) {
return time2.getTime() - time1.getTime();
}
public void setFocus() {
eventName.setFocus(true);
}
}

View file

@ -0,0 +1,229 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
/**
* A Generator for contact informations, output is in MeCard format.
*
* @author Yohann Coppel
*/
public class ContactInfoGenerator implements GeneratorSource {
Grid table = null;
TextBox name = new TextBox();
TextBox company = new TextBox();
TextBox tel = new TextBox();
TextBox url = new TextBox();
TextBox email = new TextBox();
TextBox address = new TextBox();
TextBox memo = new TextBox();
TextBox[] widgets = {name, company, tel, url, email, address, memo};
public ContactInfoGenerator(ChangeListener changeListener) {
for (TextBox w: widgets) {
w.addChangeListener(changeListener);
}
}
public String getName() {
return "Contact information";
}
public String getText() throws GeneratorException {
String name = getNameField();
String company = getCompanyField();
String tel = getTelField();
String url = getUrlField();
String email = getEmailField();
String address = getAddressField();
String memo = getMemoField();
// Build the output with obtained data.
// note that some informations may just be "" if they were not specified.
//return getVCard(name, company, tel, url, email, address, memo);
return getMeCard(name, company, tel, url, email, address, memo);
}
private String getMeCard(String name, String company, String tel, String url,
String email, String address, String memo) {
String output = "MECARD:";
output += "N:" + name + ";";
output += company.length() > 0 ? "ORG:" + company + ";" : "";
output += tel.length() > 0 ? "TEL:" + tel + ";" : "";
output += url.length() > 0 ? "URL:" + url + ";" : "";
output += email.length() > 0 ? "EMAIL:" + email + ";" : "";
output += address.length() > 0 ? "ADR:" + address + ";" : "";
output += memo.length() > 0 ? "NOTE:" + memo + ";" : "";
output += ";";
return output;
}
/*// VCARD GENERATION. Keep this in case we want to go back to vcard format
// or have the option.
private String getVCard(String name, String company, String tel, String url,
String email, String address, String memo) {
String output = "BEGIN:VCARD\n";
output += "N:" + name + "\n";
output += company.length() > 0 ? "ORG:" + company + "\n" : "";
output += tel.length() > 0 ? "TEL:" + tel + "\n" : "";
output += url.length() > 0 ? "URL:" + url + "\n" : "";
output += email.length() > 0 ? "EMAIL:" + email + "\n" : "";
output += address.length() > 0 ? "ADR:" + address + "\n" : "";
output += memo.length() > 0 ? "NOTE:" + memo + "\n" : "";
output += "END:VCARD";
return output;
}
*/
private String getNameField() throws GeneratorException {
String inputName = name.getText();
if (inputName.length() < 1) {
throw new GeneratorException("Name must be at least 1 character.");
}
if (inputName.contains("\n")) {
throw new GeneratorException("Name should not contanains \\n characters.");
}
if (inputName.contains(";")) {
throw new GeneratorException("Name must not contains ; characters");
}
return inputName;
}
private String getCompanyField() throws GeneratorException {
String input = company.getText();
if (input.length() < 1) {
return "";
}
if (input.contains("\n")) {
throw new GeneratorException("Company should not contanains \\n characters.");
}
if (input.contains(";")) {
throw new GeneratorException("Company must not contains ; characters");
}
// the input contains some informations.
return input;
}
private String getTelField() throws GeneratorException {
String input = Validators.filterNumber(tel.getText());
if (input.length() < 1) {
return "";
}
Validators.validateNumber(input);
if (input.contains(";")) {
throw new GeneratorException("Tel must not contains ; characters");
}
return input;
}
private String getUrlField() throws GeneratorException {
String input = url.getText();
if (input.length() < 1) {
return "";
}
Validators.validateUrl(input);
if (input.contains(";")) {
throw new GeneratorException("URL must not contains ; characters");
}
return input;
}
private String getEmailField() throws GeneratorException {
String input = email.getText();
if (input.length() < 1) {
return "";
}
Validators.validateEmail(input);
if (input.contains(";")) {
throw new GeneratorException("Email must not contains ; characters");
}
return input;
}
private String getAddressField() throws GeneratorException {
String input = address.getText();
if (input.length() < 1) {
return "";
}
if (input.contains("\n")) {
throw new GeneratorException("Address must not contain \\n characters.");
}
if (input.contains(";")) {
throw new GeneratorException("Address must not contains ; characters");
}
return input;
}
private String getMemoField() throws GeneratorException {
String input = memo.getText();
if (input.length() < 1) {
return "";
}
if (input.contains("\n")) {
throw new GeneratorException("Memo must not contain \\n characters.");
}
if (input.contains(";")) {
throw new GeneratorException("Memo must not contains ; characters");
}
return input;
}
public Grid getWidget() {
if (table != null) {
// early termination if the table has already been constructed
return table;
}
table = new Grid(7, 2);
table.setText(0, 0, "Name");
table.setWidget(0, 1, name);
table.setText(1, 0, "Company");
table.setWidget(1, 1, company);
table.setText(2, 0, "Phone number");
table.setWidget(2, 1, tel);
table.setText(3, 0, "Email");
table.setWidget(3, 1, email);
table.setText(4, 0, "Address");
table.setWidget(4, 1, address);
table.setText(5, 0, "Website");
table.setWidget(5, 1, url);
table.setText(6, 0, "Memo");
table.setWidget(6, 1, memo);
name.addStyleName(StylesDefs.INPUT_FIELD_REQUIRED);
return table;
}
public void validate(Widget widget) throws GeneratorException {
if (widget == name) getNameField();
if (widget == company) getCompanyField();
if (widget == tel) getTelField();
if (widget == email) getEmailField();
if (widget == address) getAddressField();
if (widget == url) getUrlField();
if (widget == memo) getMemoField();
}
public void setFocus() {
name.setFocus(true);
}
}

View file

@ -0,0 +1,75 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
/**
* Generator for email address.
*
* @author Yohann Coppel
*/
public class EmailGenerator implements GeneratorSource {
Grid table = null;
TextBox email = new TextBox();
public EmailGenerator(ChangeListener listener) {
email.addStyleName(StylesDefs.INPUT_FIELD_REQUIRED);
email.addChangeListener(listener);
}
public String getName() {
return "Email address";
}
public String getText() throws GeneratorException {
String email = getEmailField();
return "mailto:"+email;
}
private String getEmailField() throws GeneratorException {
String input = email.getText();
if (input.length() < 1) {
throw new GeneratorException("Email must be present.");
}
Validators.validateEmail(input);
return input;
}
public Grid getWidget() {
if (table != null) {
return table;
}
table = new Grid(1, 2);
table.setText(0, 0, "Address");
table.setWidget(0, 1, email);
return table;
}
public void validate(Widget widget) throws GeneratorException {
if (widget == email) getEmailField();
}
public void setFocus() {
email.setFocus(true);
}
}

View file

@ -0,0 +1,241 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.dom.client.Element;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import java.util.ArrayList;
import java.util.List;
/**
* Entry point classes define <code>onModuleLoad()</code>. Setup the page, and loads
* all different generators.
*
* @author Yohann Coppel
*/
public class Generator implements EntryPoint {
// public static final StringConstants S = GWT.create(StringConstants.class);
private final List<GeneratorSource> generators = new ArrayList<GeneratorSource>();
ListBox genList = new ListBox();
ListBox sizeList = new ListBox();
Image result = new Image("");//http://chart.apis.google.com/chart?cht=qr&chs=300x300&chl=http://google.com");
Grid topPanel = new Grid(5, 1);
GeneratorSource selectedGenerator = null;
private Button generateButton;
VerticalPanel rightPanel = new VerticalPanel();
TextBox urlResult = new TextBox();
HTML downloadText = new HTML("<a href=\"\" id=\"downloadlink\" >Download</a> or embed with this URL:");
//Element errorElement = null;
public void onModuleLoad() {
loadGenerators();
HorizontalPanel mainPanel = new HorizontalPanel();
setupLeftPanel();
topPanel.getElement().setId("leftpanel");
Widget leftPanel = topPanel;
mainPanel.add(leftPanel);
SimplePanel div = new SimplePanel();
SimplePanel div2 = new SimplePanel();
div2.add(result);
div2.getElement().setId("innerresult");
div.add(div2);
div.getElement().setId("imageresult");
urlResult.getElement().setId("urlresult");
downloadText.getElement().setId("downloadText");
rightPanel.add(div);
rightPanel.add(downloadText);
rightPanel.add(urlResult);
mainPanel.add(rightPanel);
mainPanel.getElement().setId("mainpanel");
RootPanel.get("ui").add(mainPanel);
//RootPanel.get().add(output);
//output.setHeight("200px");
//output.setWidth("500px");
setWidget(1);
invalidateBarcode();
}
private void setWidget(int id) {
if (id >= 0 && id < generators.size()) {
topPanel.setWidget(1, 0, generators.get(id).getWidget());
genList.setSelectedIndex(id);
selectedGenerator = generators.get(id);
eraseErrorMessage();
invalidateBarcode();
genList.setFocus(false);
selectedGenerator.setFocus();
}
}
private void loadGenerators() {
generators.add(new CalendarEventGenerator(changeListener));
generators.add(new ContactInfoGenerator(changeListener));
generators.add(new EmailGenerator(changeListener));
generators.add(new GeoLocationGenerator(changeListener));
generators.add(new PhoneNumberGenerator(changeListener));
generators.add(new SmsAddressGenerator(changeListener));
generators.add(new TextGenerator(changeListener));
generators.add(new UrlGenerator(changeListener));
}
public void setupLeftPanel() {
topPanel.setHTML(2, 0,
"<span id=\"errorMessageID\" class=\""+StylesDefs.ERROR_MESSAGE+"\"></span>");
// fills up the list of generators
for(GeneratorSource generator: generators) {
genList.addItem(generator.getName());
setGridStyle(generator.getWidget());
}
sizeList.addItem("S", "120");
sizeList.addItem("M", "230");
sizeList.addItem("L", "350");
sizeList.setSelectedIndex(2);
// updates the second row of the table with the content of the selected
// generator
genList.addChangeListener(new ChangeListener() {
public void onChange(Widget sender) {
int i = genList.getSelectedIndex();
setWidget(i);
}
});
// grid for the generator picker
Grid selectionTable = new Grid(1, 2);
selectionTable.setText(0, 0, "Contents");
selectionTable.setWidget(0, 1, genList);
setGridStyle(selectionTable);
topPanel.setWidget(0, 0, selectionTable);
// grid for the generate button
Grid generateGrid = new Grid(1, 2);
setGridStyle(generateGrid);
generateButton = new Button("Generate &rarr;");
generateButton.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
generate();
}
});
generateGrid.setWidget(0,1,generateButton);
topPanel.setWidget(4, 0, generateGrid);
Grid sizeTable = new Grid(1, 2);
sizeTable.setText(0, 0, "Barcode size");
sizeTable.setWidget(0, 1, sizeList);
setGridStyle(sizeTable);
topPanel.setWidget(3, 0, sizeTable);
}
protected void setGridStyle(Grid grid) {
grid.getColumnFormatter().addStyleName(0, "firstColumn");
grid.getColumnFormatter().addStyleName(1, "secondColumn");
CellFormatter cellFormatter = grid.getCellFormatter();
for(int i = 0; i < grid.getRowCount(); ++i) {
cellFormatter.addStyleName(i, 0, "firstColumn");
cellFormatter.addStyleName(i, 1, "secondColumn");
}
}
protected String getUrl(int sizeX, int sizeY, String content) {
String result = "http://chart.apis.google.com/chart?cht=qr&chs=";
result += sizeX;
result += "x";
result += sizeY;
result += "&chl=";
result += URL.encode(content);
return result;
}
private void generate() {
try {
String text = selectedGenerator.getText();
eraseErrorMessage();
int size = Integer.parseInt(sizeList
.getValue(sizeList.getSelectedIndex()));
String url = getUrl(size, size, text);
result.setUrl(url);
result.setVisible(true);
urlResult.setText(url);
urlResult.setVisible(true);
Element linkElement = DOM.getElementById("downloadlink");
linkElement.setAttribute("href", url);
downloadText.setVisible(true);
} catch (GeneratorException ex) {
invalidateBarcode();
String error = ex.getMessage();
showErrorMessage(error);
}
}
public void invalidateBarcode() {
result.setVisible(false);
urlResult.setText("");
urlResult.setVisible(false);
Element linkElement = DOM.getElementById("downloadlink");
linkElement.setAttribute("href", "");
downloadText.setVisible(false);
}
public void showErrorMessage(String error) {
Element errorElement = DOM.getElementById("errorMessageID");
errorElement.setInnerHTML(error);
}
public void eraseErrorMessage() {
Element errorElement = DOM.getElementById("errorMessageID");
errorElement.setInnerHTML("&nbsp;");
}
public ChangeListener changeListener = new ChangeListener() {
public void onChange(Widget sender) {
try {
selectedGenerator.validate(sender);
eraseErrorMessage();
} catch (GeneratorException ex) {
String error = ex.getMessage();
showErrorMessage(error);
invalidateBarcode();
}
}
};
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
/**
* An exception that can be raised by a generator when the input data contains
* errors. The getMessage() method should be used to get the error message to
* display to the user.
*
* @author Yohann Coppel
*/
public class GeneratorException extends Exception {
private static final long serialVersionUID = 1L;
public GeneratorException(String message) {
super(message);
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Widget;
/**
* Base interface for any generator.
*
* @author Yohann Coppel
*/
public interface GeneratorSource {
/**
* @return a GWT Grid object, containing the GUI.
*/
public Grid getWidget();
/**
* @return the name of the generator to be used in the GUI.
*/
public String getName();
/**
* @return the text to be encoded into the QR code.
* @throws GeneratorException if the input data contains errors.
*/
public String getText() throws GeneratorException;
/**
* @param widget the widget that was last modified, and that we want to
* validate the content.
* @throws GeneratorException if the widget contains errors.
*/
public void validate(Widget widget) throws GeneratorException;
/**
* Called when the generator is selected in the list. Using this method,
* the generator should set the focus to the first widget it defines.
*/
public void setFocus();
}

View file

@ -0,0 +1,185 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
/**
* A generator for geo location. It also accepts a google maps links and
* extracts the coordinates and query from the URL.
*
* @author Yohann Coppel
*/
public class GeoLocationGenerator implements GeneratorSource {
private static final String LON_REGEXP = "[+-]?[0-9]+(.[0-9]+)?";
private static final String LAT_REGEXP = "[+-]?[0-9]+(.[0-9]+)?";
Grid table = null;
TextBox latitude = new TextBox();
TextBox longitude = new TextBox();
TextBox query = new TextBox();
TextBox mapsLink = new TextBox();
public GeoLocationGenerator(ChangeListener listener) {
latitude.addStyleName(StylesDefs.INPUT_FIELD_REQUIRED);
longitude.addStyleName(StylesDefs.INPUT_FIELD_REQUIRED);
latitude.addChangeListener(listener);
longitude.addChangeListener(listener);
query.addChangeListener(listener);
}
public String getName() {
return "Geo location";
}
public String getText() throws GeneratorException {
String que = getQueryField();
if (null != que && que.length() > 0) {
if (null == getLatitudeField()) {
latitude.setText("0");
}
if (null == getLongitudeField()) {
longitude.setText("0");
}
}
String lat = getLatitudeField();
String lon = getLongitudeField();
if (que.length() > 0) {
return "geo:"+lat+","+lon+"?q="+que;
}
return "geo:"+lat+","+lon;
}
private String getQueryField() {
String que = query.getText();
que = que.replace("&", "%26");
return que;
}
private String getLongitudeField() throws GeneratorException {
String lon = longitude.getText();
if (!lon.matches(LON_REGEXP)) {
throw new GeneratorException("Longitude is not a correct value.");
}
double val = Double.parseDouble(lon);
if (val < -180 || val > 180) {
throw new GeneratorException("Longitude must be in [-180:180]");
}
return lon;
}
private String getLatitudeField() throws GeneratorException {
String lat = latitude.getText();
if (!lat.matches(LAT_REGEXP)) {
throw new GeneratorException("Latitude is not a correct value.");
}
double val = Double.parseDouble(lat);
if (val < -90 || val > 90) {
throw new GeneratorException("Latitude must be in [-90:90]");
}
return lat;
}
public Grid getWidget() {
if (table != null) {
return table;
}
table = new Grid(5, 2);
table.setText(0, 0, "Latitude");
table.setWidget(0, 1, latitude);
table.setText(1, 0, "Longitude");
table.setWidget(1, 1, longitude);
table.setText(2, 0, "Query");
table.setWidget(2, 1, query);
table.setText(3, 0, "OR");
table.setText(3, 1, "enter a Google Maps link and click Fill:");
// looks like this:
// http://maps.google.com/?ie=UTF8&ll=40.741404,-74.00322&spn=0.001484,0.003101&z=18
Button fill = new Button("Fill &uarr;");
fill.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
fillWithMaps();
}
});
table.setWidget(4, 0, fill);
table.setWidget(4, 1, mapsLink);
return table;
}
protected void fillWithMaps() {
String link = mapsLink.getText();
if (!link.matches("http://maps.google.com/.*")) {
return;
}
String q = "";
if (link.matches(".*&q=[^&]*&.*")) {
for (int i = link.indexOf("&q=") + 3;
i < link.length() && link.charAt(i) != '&'; ++i) {
q += link.charAt(i);
}
// special cases:
q = q.replace("+", " ");
q = q.replace("%26", "&");
}
String lat = "";
String lon = "";
if (link.matches(".*&s?ll=[^&]*&.*")) {
boolean beforeComa = true;
int start = 0;
if (link.indexOf("&sll=") == -1) {
start = link.indexOf("&ll=") + 4;
} else {
start = link.indexOf("&sll=") + 5;
}
for (int i = start; i < link.length() && link.charAt(i) != '&'; ++i) {
if (beforeComa) {
if (link.charAt(i) == ',') {
beforeComa = false;
} else {
lat += link.charAt(i);
}
} else {
lon += link.charAt(i);
}
}
}
query.setText(URL.decode(q));
latitude.setText(lat);
longitude.setText(lon);
}
public void validate(Widget widget) throws GeneratorException {
if (widget == latitude) getLatitudeField();
if (widget == longitude) getLongitudeField();
}
public void setFocus() {
latitude.setFocus(true);
}
}

View file

@ -0,0 +1,76 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
/**
* A generator for a phone number.
*
* @author Yohann Coppel
*/
public class PhoneNumberGenerator implements GeneratorSource {
Grid table = null;
TextBox number = new TextBox();
public PhoneNumberGenerator(ChangeListener listener) {
number.addStyleName(StylesDefs.INPUT_FIELD_REQUIRED);
number.addChangeListener(listener);
}
public String getName() {
return "Phone number";
}
public String getText() throws GeneratorException {
String tel = getTelField();
return "tel:" + tel;
}
private String getTelField() throws GeneratorException {
String input = number.getText();
if (input.length() < 1) {
throw new GeneratorException("Phone number must be present.");
}
input = Validators.filterNumber(input);
Validators.validateNumber(input);
return input;
}
public Grid getWidget() {
if (table != null) {
return table;
}
table = new Grid(1, 2);
table.setText(0, 0, "Phone number");
table.setWidget(0, 1, number);
return table;
}
public void validate(Widget widget) throws GeneratorException {
if (widget == number) getTelField();
}
public void setFocus() {
number.setFocus(true);
}
}

View file

@ -0,0 +1,100 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
/**
* A generator for a sms address. Gives the option of filling up the content
* of the message as well.
*
* @author Yohann Coppel
*/
public class SmsAddressGenerator implements GeneratorSource {
Grid table = null;
TextBox number = new TextBox();
TextArea message = new TextArea();
public SmsAddressGenerator(ChangeListener listener) {
number.addStyleName(StylesDefs.INPUT_FIELD_REQUIRED);
number.addChangeListener(listener);
message.addChangeListener(listener);
}
public String getName() {
return "SMS";
}
public String getText() throws GeneratorException {
String inputNumber = getTelField();
String inputMessage = getMessageField();
String output = inputNumber;
// we add the text only if there actually is something in the field.
if (inputMessage.length() > 0) {
output += ":" + inputMessage;
}
return "smsto:" + output;
}
private String getTelField() throws GeneratorException {
String input = number.getText();
if (input.length() < 1) {
throw new GeneratorException("Phone number must be present.");
}
input = Validators.filterNumber(input);
Validators.validateNumber(input);
return input;
}
private String getMessageField() throws GeneratorException {
String inputMessage = message.getText();
if (inputMessage.length() > 150) {
throw new GeneratorException("Sms message can not be longer than 150 characters.");
}
return inputMessage;
}
public Grid getWidget() {
if (table != null) {
return table;
}
table = new Grid(2, 2);
table.setText(0, 0, "Phone number");
table.setWidget(0, 1, number);
table.setText(1, 0, "Message");
table.setWidget(1, 1, message);
return table;
}
public void validate(Widget widget) throws GeneratorException {
if (widget == number) getTelField();
if (widget == message) getMessageField();
}
public void setFocus() {
number.setFocus(true);
}
}

View file

@ -0,0 +1,25 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
import com.google.gwt.i18n.client.Messages;
// Not used yet. A first atempt to localization.
public interface StringConstants extends Messages {
public String codeType();
public String generateButton();
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
/**
* Contains class names of css styles to be used in HTML.
*
* @author Yohann Coppel
*/
public class StylesDefs {
public static final String INPUT_FIELD_REQUIRED = "required";
public static final String ERROR_MESSAGE = "errorMessage";
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.Widget;
/**
* A generator for any text content.
*
* @author Yohann Coppel
*/
public class TextGenerator implements GeneratorSource {
TextArea text = new TextArea();
Grid table = null;
String error = "";
public TextGenerator(ChangeListener listener) {
text.addStyleName(StylesDefs.INPUT_FIELD_REQUIRED);
text.addChangeListener(listener);
}
public String getName() {
return "Text";
}
public String getText() throws GeneratorException {
String message = getTextField();
return message;
}
public String getTextField() throws GeneratorException {
String input = text.getText();
if (input.length() == 0) {
throw new GeneratorException("Text should be at least 1 character.");
}
return input;
}
public Grid getWidget() {
if (table != null) {
// early termination if the table has already been constructed
return table;
}
table = new Grid(1, 2);
table.getColumnFormatter().addStyleName(0, "firstColumn");
table.setText(0, 0, "Text content");
table.setWidget(0, 1, text);
return table;
}
public String getErrorMessage() {
return error;
}
public void validate(Widget widget) throws GeneratorException {
if (widget == text) getTextField();
}
public void setFocus() {
text.setFocus(true);
}
}

View file

@ -0,0 +1,78 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
/**
* A class containing a list of timezones, with their full names, and time
* offset.
*
* @author Yohann Coppel
*/
public class TimeZoneList {
public static class TimeZoneInfo {
String abreviation;
String longName;
String GMTRelative;
long gmtDiff;
public TimeZoneInfo(String abreviation, String longName, String relative, long gmtDiff) {
super();
GMTRelative = relative;
this.abreviation = abreviation;
this.gmtDiff = gmtDiff;
this.longName = longName;
}
}
private final static long ONE_HOUR = 60*60*1000;
private final static long THIRTY_MIN = 30*60*1000;
public static final TimeZoneInfo[] TIMEZONES = {
new TimeZoneInfo("GMT", "Greenwich Mean Time", "GMT", 0 * ONE_HOUR + 0 * THIRTY_MIN), // 0
new TimeZoneInfo("UTC", "Universal Coordinated Time", "GMT", 1 * ONE_HOUR + 0 * THIRTY_MIN),
new TimeZoneInfo("ECT", "European Central Time", "GMT+1:00", 1 * ONE_HOUR + 0 * THIRTY_MIN),
new TimeZoneInfo("EET", "Eastern European Time", "GMT+2:00", 2 * ONE_HOUR + 0 * THIRTY_MIN),
new TimeZoneInfo("ART", "(Arabic) Egypt Standard Time", "GMT+2:00", 2 * ONE_HOUR + 0 * THIRTY_MIN),
new TimeZoneInfo("EAT", "Eastern African Time", "GMT+3:00", 3 * ONE_HOUR + 0 * THIRTY_MIN), // 5
new TimeZoneInfo("MET", "Middle East Time", "GMT+3:30", 3 * ONE_HOUR + 1 * THIRTY_MIN),
new TimeZoneInfo("NET", "Near East Time", "GMT+4:00", 4 * ONE_HOUR + 0 * THIRTY_MIN),
new TimeZoneInfo("PLT", "Pakistan Lahore Time", "GMT+5:00", 5 * ONE_HOUR + 0 * THIRTY_MIN),
new TimeZoneInfo("IST", "India Standard Time", "GMT+5:30", 5 * ONE_HOUR + 1 * THIRTY_MIN),
new TimeZoneInfo("BST", "Bangladesh Standard Time", "GMT+6:00", 6 * ONE_HOUR + 0 * THIRTY_MIN), // 10
new TimeZoneInfo("VST", "Vietnam Standard Time", "GMT+7:00", 7 * ONE_HOUR + 0 * THIRTY_MIN),
new TimeZoneInfo("CTT", "China Taiwan Time", "GMT+8:00", 8 * ONE_HOUR + 0 * THIRTY_MIN),
new TimeZoneInfo("JST", "Japan Standard Time", "GMT+9:00", 9 * ONE_HOUR + 0 * THIRTY_MIN),
new TimeZoneInfo("ACT", "Australia Central Time", "GMT+9:30", 9 * ONE_HOUR + 1 * THIRTY_MIN),
new TimeZoneInfo("AET", "Australia Eastern Time", "GMT+10:00", 10 * ONE_HOUR + 0 * THIRTY_MIN), // 15
new TimeZoneInfo("SST", "Solomon Standard Time", "GMT+11:00", 11 * ONE_HOUR + 0 * THIRTY_MIN),
new TimeZoneInfo("NST", "New Zealand Standard Time", "GMT+12:00", 12 * ONE_HOUR + 0 * THIRTY_MIN),
new TimeZoneInfo("MIT", "Midway Islands Time", "GMT-11:00", -11 * ONE_HOUR - 0 * THIRTY_MIN),
new TimeZoneInfo("HST", "Hawaii Standard Time", "GMT-10:00", -10 * ONE_HOUR - 0 * THIRTY_MIN),
new TimeZoneInfo("AST", "Alaska Standard Time", "GMT-9:00", -9 * ONE_HOUR - 0 * THIRTY_MIN), // 20
new TimeZoneInfo("PST", "Pacific Standard Time", "GMT-8:00", -8 * ONE_HOUR - 0 * THIRTY_MIN),
new TimeZoneInfo("PNT", "Phoenix Standard Time", "GMT-7:00", -7 * ONE_HOUR - 0 * THIRTY_MIN),
new TimeZoneInfo("MST", "Mountain Standard Time", "GMT-7:00", -7 * ONE_HOUR - 0 * THIRTY_MIN),
new TimeZoneInfo("CST", "Central Standard Time", "GMT-6:00", -6 * ONE_HOUR - 0 * THIRTY_MIN),
new TimeZoneInfo("EST", "Eastern Standard Time", "GMT-5:00", -5 * ONE_HOUR - 0 * THIRTY_MIN), // 25
new TimeZoneInfo("IET", "Indiana Eastern Standard Time", "GMT-5:00", -5 * ONE_HOUR - 0 * THIRTY_MIN),
new TimeZoneInfo("PRT", "Puerto Rico and US Virgin Islands Time", "GMT-4:00", -4 * ONE_HOUR - 0 * THIRTY_MIN),
new TimeZoneInfo("CNT", "Canada Newfoundland Time", "GMT-3:30", -3 * ONE_HOUR - 1 * THIRTY_MIN),
new TimeZoneInfo("AGT", "Argentina Standard Time", "GMT-3:00", -3 * ONE_HOUR - 0 * THIRTY_MIN),
new TimeZoneInfo("BET", "Brazil Eastern Time", "GMT-3:00", -3 * ONE_HOUR - 0 * THIRTY_MIN), // 30
new TimeZoneInfo("CAT", "Central African Time", "GMT-1:00", -1 * ONE_HOUR - 0 * THIRTY_MIN),
};
}

View file

@ -0,0 +1,77 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
/**
* A generator for URL addresses.
*
* @author Yohann Coppel
*/
public class UrlGenerator implements GeneratorSource {
Grid table = null;
TextBox url = new TextBox();
public UrlGenerator(ChangeListener listener) {
url.addStyleName(StylesDefs.INPUT_FIELD_REQUIRED);
url.addChangeListener(listener);
}
public Grid getWidget() {
if (table != null) {
// early termination if the table has already been constructed
return table;
}
table = new Grid(1, 2);
table.getColumnFormatter().addStyleName(0, "firstColumn");
url.setText("http://");
table.setText(0, 0, "URL");
table.setWidget(0, 1, url);
return table;
}
public String getName() {
return "URL";
}
public String getText() throws GeneratorException {
String input = getUrlField();
return input;
}
private String getUrlField() throws GeneratorException {
String input = url.getText();
Validators.validateUrl(input);
return input;
}
public void validate(Widget widget) throws GeneratorException {
if (widget == url) getUrlField();
}
public void setFocus() {
url.setFocus(true);
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.web.generator.client;
/**
* Helpers methods to check for phone numbers, email addresses, and URL. Other
* general purpose check methods should go here as well.
*
* @author Yohann Coppel
*/
public final class Validators {
public static String filterNumber(String number) {
return number.replaceAll("[ +\\.,\\-\\(\\)]", "");
}
public static void validateNumber(String number) throws GeneratorException {
if (!number.matches("[0-9]+")) {
throw new GeneratorException("Phone number must be digits only.");
}
}
public static void validateUrl(String url) throws GeneratorException {
//FIXME: url specification is a bit more complex than just that.
if (!((url.startsWith("http://") && url.length() > 7)
|| (url.startsWith("https://") && url.length() > 8))) {
throw new GeneratorException("URL: http:// or https://," +
"plus at least 1 character.");
}
}
public static void validateEmail(String email) throws GeneratorException {
//FIXME: we can have a better check for email here.
if (!email.matches("^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$")) {
throw new GeneratorException("Email is not valid.");
}
}
}

View file

@ -0,0 +1,180 @@
/**
Date picker styles, most of these will eventually move into a default resource bundle.
*/
.gwt-DatePicker {
width: 150px;
border: 1px solid #f1f1f1;
border-bottom: 2px solid #f1f1f1;
color: 6b6b6b;
cursor: default;
}
.gwt-DatePicker td {
font-family: Arial;
font-size: 65%;
padding: 2px;
text-align: center;
padding: 2px;
outline: none;
-moz-outline: none;
cursor: default;
}
.gwt-DatePicker td,.month-selector td :focus {
outline: none
}
.gwt-DateBox input {
width: 8em;
}
/**
Calendar styles
*/
.calendar-view {
background-color: white;
width: 100%;
}
.calendar-view .filler-cell {
color: #bfbfbf;
padding: 1px;
cursor: hand;
}
.calendar-view .date-cell {
padding: 1px;
cursor:hand;
}
.calendar-view .selected-cell {
background: #aaccee;
}
.calendar-view .day-title {
background: #dbe6de;
}
.gwt-DatePicker .calendar-view .highlighted-cell {
border: 1px solid #eeeeee;
padding: 0px;
}
.calendar-view .today-cell {
border: 1px solid black;
padding: 0px;
}
.gwt-DatePicker .calendar-view .weekend {
background: #f1f1f1;
}
.calendar-view .disabled-cell {
color: graytext;
}
/*
Month selector styles
*/
.month-selector {
background: #dbe6de;
width: 100%;
text-align: center;
}
.month-selector td {
font-weight: bold;
font-size: 70%;
}
.month-selector .month-label {
text-align: center;
background: #dbe6de;
}
.month-selector .month-backward {
padding-right: 2em;
}
.month-selector .month-forward {
padding-left: 2em;
}
/****************************
helper styles
******************************/
.log-panel {
position: relative;
float: right;
border: 1px solid black;
margin-left: 30px;
}
.gwt-TabPanel {
margin-top: 4px;
}
.gwt-TabPanelBottom {
background-color: #E8EEF7;
}
.gwt-TabBar {
padding-top: 2px;
border-bottom: 4px solid #87B3FF;
background-color: #fff;
}
.gwt-TabBar .gwt-TabBarItem {
padding: 4px;
cursor: pointer;
cursor: hand;
background-color: #e8eef7;
border-bottom: 2px solid white;
margin-right: 2px;
}
.gwt-TabBar .gwt-TabBarItem-selected {
padding: 4px;
font-weight: bold;
cursor: default;
background-color: #87b3ff;
border-bottom: 2px solid #87b3ff;
margin-right: 2px;
}
/* Styles demo*/
.gwt-DatePicker .red-date {
background-color: red;
}
.gwt-DatePicker .blue-background {
background-color: blue;
}
.gwt-DatePicker .red-text {
color: red;
}
.gwt-DatePicker .green-border {
border: 5px solid green;
}
.gwt-DatePicker .big-text {
font-size: x-large;
}
.gwt-DatePicker .underlined-and-bold-text {
font-weight: bold;
text-decoration: underline;
}
.gwt-DatePicker .yellow-background {
background-color: yellow;
}
/* date range styles */
.filler {
width: 30px;
text-align: center;
}

View file

@ -0,0 +1,123 @@
/** CSS by Wain. */
body {
background-color: #e9eef3;
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
font-size: 11px;
}
#header {
background-color: #dde3e9;
border-bottom: 1px solid #f2f7fc;
}
#header h1 {
font-size: 15px;
font-weight: bold;
margin: 0;
padding: 12px;
border-bottom: 1px solid #c8d0d9;
}
#header span {
font-weight: normal;
color: #5e6b75;
}
#footer {
width: 100%;
text-align:center;
padding-top: 12px;
}
#footer a {
text-decoration:none;
color: #5e6b75;
}
/****************************************/
#mainpanel {
width: 800px;
margin: 0 auto;
padding: 12px;
font-size: 11px;
}
#imageresult {
background-color: #dde3e9;
height: 350px;
width: 350px;
vertical-align: middle;
text-align:center;
padding: 10px;
position: relative;
display: table;
#position: relative;
}
#innerresult {
display: table-cell;
vertical-align: middle;
width: 100%;
#position: absolute;
#top: 50%;
}
#innerresult img {
#position: relative;
#top: -50%;
}
#downloadText {
font-size: 11px;
}
#urlresult {
width: 350px;
}
.firstColumn {
width: 100px;
text-align: right;
vertical-align: top;
padding: 4px 0 4px 0;
color: #5e6b75;
font-weight: bold;
font-size: 11px;
}
.secondColumn {
width: 270px;
font-size: 11px;
color: #5e6b75;
font-weight: bold;
}
/*.inputfield,*/
.gwt-TextBox,
.gwt-TextArea {
border: 1px solid #c8d0d9;
padding: 4px;
width: 256px;
font-family: Arial, sans-serif;
font-size: 13px;
color: #000;
font-weight: normal;
}
/*.inputfield:focus,*/
.gwt-TextBox:focus {
background-color: #fffbcc;
}
.required {
background: #ffffff url(required-field-bg.png) repeat-y;
}
.errorMessage {
padding-left: 110px;
font-size: 11px;
color: red;
}

View file

@ -0,0 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>QR Code Generator</title>
<script type="text/javascript" language="javascript" src="com.google.zxing.web.generator.Generator.nocache.js"></script>
<link rel="stylesheet" href="Generator.css" type="text/css"/>
</head>
<body>
<div id="header">
<h1>QR Code Generator <span>from the ZXing Project</span></h1>
</div>
<div id="ui"></div>
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
<div id="footer">
<a href="http://code.google.com/p/zxing/">ZXing Project Home Page</a>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

View file

@ -0,0 +1,17 @@
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
class BlogHandler(webapp.RequestHandler):
def get(self, tail = ''):
self.redirect('/generator/'+tail, permanent = True)
application = webapp.WSGIApplication(
[
(r'^/generator$', BlogHandler)
])
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()