diff --git a/app/controllers/schema_browser_controller.rb b/app/controllers/schema_browser_controller.rb
new file mode 100644
index 00000000..a49e0773
--- /dev/null
+++ b/app/controllers/schema_browser_controller.rb
@@ -0,0 +1,9 @@
+class SchemaBrowserController < ApplicationController
+ layout "schema_browser", :except => [:schema]
+
+ def schema
+ respond_to do |format|
+ format.xml
+ end
+ end
+end
diff --git a/app/views/layouts/schema_browser.html.erb b/app/views/layouts/schema_browser.html.erb
new file mode 100644
index 00000000..a1d4a81d
--- /dev/null
+++ b/app/views/layouts/schema_browser.html.erb
@@ -0,0 +1,130 @@
+
+
+
+
+ SQL Designer
+ <%= stylesheet_link_tag "schema_browser/style" %>
+ <%= javascript_include_tag "schema_browser/settings" %>
+ <%= javascript_include_tag "schema_browser/style" %>
+ <%= javascript_include_tag "schema_browser/generic" %>
+ <%= javascript_include_tag "schema_browser/ajax" %>
+ <%= javascript_include_tag "schema_browser/sql_types" %>
+ <%= javascript_include_tag "schema_browser/main" %>
+ <%= javascript_include_tag "schema_browser/objects" %>
+ <%= javascript_include_tag "schema_browser/animator" %>
+ <%= javascript_include_tag "schema_browser/io" %>
+
+
+
+
+
+
+
+
+
+
TABLE
+
+
New table
+
Delete table
+
Align tables
+
+
Clear tables
+
+
+
+
ROW
+
+
Add row
+
+
Delete row
+
Up
+
Down
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
(
+
+
)
+
+
+
+
IMPORT/EXPORT
+
+
GO!
+
Settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/views/schema_browser/index.html.erb b/app/views/schema_browser/index.html.erb
new file mode 100644
index 00000000..28451c2f
--- /dev/null
+++ b/app/views/schema_browser/index.html.erb
@@ -0,0 +1 @@
+Content from index
diff --git a/app/views/schema_browser/schema.xml.builder b/app/views/schema_browser/schema.xml.builder
new file mode 100644
index 00000000..4ab82680
--- /dev/null
+++ b/app/views/schema_browser/schema.xml.builder
@@ -0,0 +1,24 @@
+schema_browser = SchemaBrowser.new
+xml.instruct!
+xml.sql {
+ schema_browser.tables.each { |table|
+ xml.table(table.attributes) {
+ table.columns.each { |column|
+ xml.row(column.attributes) {
+ xml.title(column.name)
+ xml.default(column.default)
+ xml.type(column.type)
+ }
+ }
+ }
+ }
+
+ schema_browser.relations.each { |relation|
+ xml.relation {
+ xml.table_1(relation.origin_table_id)
+ xml.row_1(relation.origin_row_id)
+ xml.table_2(relation.destination_table_id)
+ xml.row_2(relation.destination_row_id)
+ }
+ }
+}
diff --git a/public/images/schema_browser/back.gif b/public/images/schema_browser/back.gif
new file mode 100644
index 00000000..0e93eaaa
Binary files /dev/null and b/public/images/schema_browser/back.gif differ
diff --git a/public/images/schema_browser/h_1-n.gif b/public/images/schema_browser/h_1-n.gif
new file mode 100644
index 00000000..84909b94
Binary files /dev/null and b/public/images/schema_browser/h_1-n.gif differ
diff --git a/public/images/schema_browser/h_n-1.gif b/public/images/schema_browser/h_n-1.gif
new file mode 100644
index 00000000..df34f5e2
Binary files /dev/null and b/public/images/schema_browser/h_n-1.gif differ
diff --git a/public/images/schema_browser/move_cross.gif b/public/images/schema_browser/move_cross.gif
new file mode 100644
index 00000000..e742bb50
Binary files /dev/null and b/public/images/schema_browser/move_cross.gif differ
diff --git a/public/images/schema_browser/shadow.png b/public/images/schema_browser/shadow.png
new file mode 100644
index 00000000..941a4a83
Binary files /dev/null and b/public/images/schema_browser/shadow.png differ
diff --git a/public/images/schema_browser/shadow_bottom.png b/public/images/schema_browser/shadow_bottom.png
new file mode 100644
index 00000000..0890c8ef
Binary files /dev/null and b/public/images/schema_browser/shadow_bottom.png differ
diff --git a/public/images/schema_browser/shadow_corner.png b/public/images/schema_browser/shadow_corner.png
new file mode 100644
index 00000000..e5e86dea
Binary files /dev/null and b/public/images/schema_browser/shadow_corner.png differ
diff --git a/public/images/schema_browser/shadow_right.png b/public/images/schema_browser/shadow_right.png
new file mode 100644
index 00000000..0f4600f7
Binary files /dev/null and b/public/images/schema_browser/shadow_right.png differ
diff --git a/public/images/schema_browser/v_1-n.gif b/public/images/schema_browser/v_1-n.gif
new file mode 100644
index 00000000..4c986dab
Binary files /dev/null and b/public/images/schema_browser/v_1-n.gif differ
diff --git a/public/images/schema_browser/v_n-1.gif b/public/images/schema_browser/v_n-1.gif
new file mode 100644
index 00000000..b162bf02
Binary files /dev/null and b/public/images/schema_browser/v_n-1.gif differ
diff --git a/public/javascripts/schema_browser/ajax.js b/public/javascripts/schema_browser/ajax.js
new file mode 100644
index 00000000..532b655e
--- /dev/null
+++ b/public/javascripts/schema_browser/ajax.js
@@ -0,0 +1,163 @@
+/*
+ ajax_command(method, target, data_func, return_func);
+ ajax_manage(id, event, method, target, data_func, return_func);
+*/
+
+var GET = 1;
+var POST = 2;
+
+function ajax_command(method, target, data_func, return_func) {
+ var xmlhttp = new XMLHTTP();
+ var data = null; /* default - no data */
+ var callback_response = function() {
+ if (xmlhttp.getReadyState() == 4) {
+ if (xmlhttp.getStatus() == 200) {
+ return_func(xmlhttp.getResponseText());
+ } else {
+ xmlhttp.error("problem retrieving data");
+ }
+ } /* response complete */
+ } /* callback_response */
+ xmlhttp.setResponse(callback_response);
+
+ data = data_func(); /* request them from some user-specified routine */
+
+ switch (method) {
+ case GET:
+ var newtarget = (/\?/.test(target) ? target+"&"+data : target+"?"+data);
+ xmlhttp.open("GET",newtarget,true);
+ break;
+ case POST:
+ xmlhttp.open("POST",target,true);
+ xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
+ break;
+ } /* method */
+ xmlhttp.send(data); /* off we go */
+}
+
+function ajax_manage(id, event, method, target, data_func, return_func) {
+ var element = document.getElementById(id);
+ if (!element) {
+ alert("Element '"+id+"' not found");
+ return;
+ }
+ if (method == POST && !XMLHTTP_supported()) {
+ alert("IFRAME mode active -> POSTs not allowed");
+ return;
+ }
+ var callback_request = function() {
+ ajax_command(method,target,data_func,return_func);
+ } /* callback_request */
+
+ universalAttacher(element,event,callback_request);
+}
+
+function XMLHTTP_error(text) {
+ alert('XMLHTTP error: "'+text+'", sorry...');
+}
+
+function XMLHTTP_open(method, target, async) {
+ if (this.iframe) {
+ this.temp_src = target;
+ } else {
+ this.obj.open(method, target, async);
+ }
+}
+
+function XMLHTTP_send(data) {
+ if (this.iframe) {
+ this.ifr.src = this.temp_src;
+ } else {
+ this.obj.send(data);
+ }
+}
+
+function XMLHTTP_setResponse(callback) {
+ if (this.iframe) {
+ universalAttacher(this.ifr,"load",callback);
+ } else {
+ this.obj.onreadystatechange = callback;
+ }
+}
+
+function XMLHTTP_getResponseText() {
+ if (this.iframe) {
+ var data = this.ifr.contentWindow.document.body.innerHTML;
+ /* uncomment this to save memory and confuse gecko: */
+ /* this.ifr.parentNode.removeChild(this.ifr); */
+ return data;
+ } else {
+ return this.obj.responseText;
+ }
+}
+
+function XMLHTTP_getResponseXML() {
+ if (this.iframe) {
+ this.error("IFRAME mode active -> XML data not supported");
+ return "";
+ } else {
+ return this.obj.responseXML;
+ }
+}
+
+function XMLHTTP_getReadyState() {
+ if (this.iframe) {
+ return 4;
+ } else {
+ return this.obj.readyState;
+ }
+}
+
+function XMLHTTP_getStatus() {
+ if (this.iframe) {
+ return 200;
+ } else {
+ return this.obj.status;
+ }
+}
+
+function XMLHTTP_setRequestHeader(name,value) {
+ if (!this.iframe) {
+ this.obj.setRequestHeader(name,value);
+ }
+}
+
+function XMLHTTP_isIframe() {
+ return this.iframe;
+}
+
+function XMLHTTP() {
+ this.iframe = false;
+ this.open = XMLHTTP_open;
+ this.send = XMLHTTP_send;
+ this.error = XMLHTTP_error;
+ this.setResponse = XMLHTTP_setResponse;
+ this.getResponseText = XMLHTTP_getResponseText;
+ this.getResponseXML = XMLHTTP_getResponseXML;
+ this.getReadyState = XMLHTTP_getReadyState;
+ this.getStatus = XMLHTTP_getStatus;
+ this.setRequestHeader = XMLHTTP_setRequestHeader;
+ this.isIframe = XMLHTTP_isIframe;
+ this.obj = false;
+
+ if (window.XMLHttpRequest) {
+ /* gecko */
+ this.obj = new XMLHttpRequest();
+ } else if (window.ActiveXObject) {
+ /* ie */
+ this.obj = new ActiveXObject("Microsoft.XMLHTTP");
+ }
+ if (!this.obj) {
+ /* no luck -> iframe */
+ this.iframe = true;
+ this.ifr = document.createElement("iframe");
+ this.ifr.style.display = "none";
+ this.ifr.src = "javascript:;";
+ document.body.appendChild(this.ifr);
+ }
+}
+
+function XMLHTTP_supported() {
+ var dummy = new XMLHTTP();
+ return (!dummy.isIframe());
+}
diff --git a/public/javascripts/schema_browser/animator.js b/public/javascripts/schema_browser/animator.js
new file mode 100644
index 00000000..81c73868
--- /dev/null
+++ b/public/javascripts/schema_browser/animator.js
@@ -0,0 +1,78 @@
+/*
+ WWW SQL Designer, (C) 2005 Ondra Zara, o.z.fw@seznam.cz
+
+ This file is part of WWW SQL Designer.
+
+ WWW SQL Designer 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.
+
+ WWW SQL Designer 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 WWW SQL Designer; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+var animation_lock = 0; /* kolik prave bezi animaci */
+var animation_end_queue = Array(); /* az skonci _posledni_ animace, tohle vsecko spustime */
+
+function animation_queue_add(funcRef) {
+ var i = get_free_index(animation_end_queue);
+ animation_end_queue[i] = funcRef;
+}
+
+function animation_function(row_element,direction,endFunc) {
+ var h = parseInt(row_element.style.height);
+ h=h+direction;
+ row_element.style.height = h+"px";
+
+ if ((direction == 1 && h < ROW_HEIGHT) || (direction == -1 && h > 1)) {
+ var funcRef = function() {
+ animation_function(row_element,direction,endFunc);
+ }
+ setTimeout(funcRef,DELAY);
+ } else {
+ var funcRef = function() {
+ end_animation(row_element,direction,endFunc);
+ }
+ setTimeout(funcRef,0);
+ }
+}
+
+function start_animation(row_element,direction,endFunc) {
+ animation_lock++;
+ var number = parseInt(row_element.getAttribute("parent_number"));
+ table_array[number].hideShadow();
+
+ var h;
+ if (direction == 1) {
+ h = 1;
+ }
+ if (direction == -1) {
+ h = ROW_HEIGHT;
+ }
+ row_element.style.height = h+ "px";
+ var funcRef = function() {
+ animation_function(row_element,direction,endFunc);
+ }
+ setTimeout(funcRef,DELAY);
+}
+
+function end_animation(row_element,direction,endFunc) {
+ animation_lock--;
+ if (endFunc) { /* na konci kazde animace muze neco byt */
+ endFunc();
+ }
+ if (!animation_lock) { /* az skonci posledni animace, jeste neco pustime */
+ for (var i=0;i([^<]*)<\/table_1>/);
+ var table_2 = relation.match(/([^<]*)<\/table_2>/);
+ var row_1 = relation.match(/([^<]*)<\/row_1>/);
+ var row_2 = relation.match(/([^<]*)<\/row_2>/);
+ add_relation(table_1[1],row_1[1],table_2[1],row_2[1]);
+}
+
+function import_xml_row(table, row) {
+ var r;
+ var head = row.match(/]*>/);
+ var id = head[0].match(/id="([^"]*)"/);
+
+ var title = row.match(/([^<]*)<\/title>/);
+ var stype = row.match(/([^<]*)<\/type>/);
+ var type=13; /* default -> UNKNOWN */
+ for (var i=0;i([^<]*)<\/default>/);
+ r.setDef(def[1]);
+ var index = head[0].match(/index="[^"]*"/);
+ if (index) {
+ r.setIndex();
+ }
+ var pk = head[0].match(/pk="[^"]*"/);
+ if (pk) {
+ r.setPK();
+ }
+ var fk = head[0].match(/fk="[^"]*"/);
+ if (fk) {
+ r.setFK();
+ }
+ var nn = head[0].match(/nn="[^"]*"/);
+ if (nn) {
+ r.setNN();
+ }
+ var spec = head[0].match(/special="([^"]*)"/);
+ if (spec) {
+ r.setSpec(spec[1]);
+ }
+}
+
+
+function import_xml_table(table) {
+ var t;
+ var pos_x=0;
+ var pos_y=0;
+ var head = table.match(/]*>/);
+ var id = head[0].match(/id="([^"]*)"/);
+ var title = head[0].match(/title="([^"]*)"/);
+ var x = head[0].match(/x="([^"]*)"/);
+ var y = head[0].match(/y="([^"]*)"/);
+ if (x) { pos_x = x[1]; } else { reposition = 1;}
+ if (y) { pos_y = y[1]; } else { reposition = 1;}
+ if (id) {
+ t = add_table(pos_x,pos_y,title[1],id[1]);
+ } else {
+ t = add_table(pos_x,pos_y,title[1]);
+ }
+ var rows = table.match(/]*>.*?<\/row>/g);
+ for (var i=0;i */
+ var clear = data.match(/(.*)<\/sql>/);
+ if (!clear) {
+ alert('No data!');
+ return;
+ }
+
+ /* vsechno vycistime */
+ clear_tables();
+
+ /* a jedeme - tabulky */
+ var tables = clear[1].match(/]*>.*?<\/table>/g);
+ for (var i=0;i]*>.*?<\/relation>/g);
+ if (relations) {
+ for (var i=0;i
+
+
+
+
+ 0
+ id
+ Integer
+
+
+ Integer
+ 0
+ id_neco
+
+
+ String
+ hodnota
+
+
+
+ 3
+ 4
+ 0
+ 0
+
+
+ */
+
+ /* hlavicka */
+ var x,y;
+ var str, row;
+ var data = '\n';
+ data += '\n';
+ data += '\n';
+
+ /* tabulky a radky */
+ for (var i=0;i\n';
+ for (var j=0;j\n';
+ data += '\t\t\t'+row._title.innerHTML+'\n';
+ data += '\t\t\t'+row.def+'\n';
+ data += '\t\t\t'+SQL_TYPES_DEFAULT[row.type]+'\n';
+ data += '\t\t\n';
+ } /* pro vsechny radky */
+ data += '\t
\n';
+ } /* pokud tabulka existuje */
+ } /* pro vsechny tabulky */
+
+ /* relace */
+ var table_1, table_2, row_1, row_2;
+ for (var k=0;k\n';
+ data += '\t\t'+table_1+'\n';
+ data += '\t\t'+row_1+'\n';
+ data += '\t\t'+table_2+'\n';
+ data += '\t\t'+row_2+'\n';
+ data += '\t\n';
+ }
+ }
+
+ /* paticka */
+ data += '';
+ return data;
+}
+
+
+function io_show(import_btn) {
+ var btn = document.getElementById("import");
+ if (import_btn) {
+ btn.style.display = "block";
+ } else {
+ btn.style.display = "none";
+ }
+ var area = document.getElementById("area");
+ area.parentNode.style.display = "block";
+}
\ No newline at end of file
diff --git a/public/javascripts/schema_browser/main.js b/public/javascripts/schema_browser/main.js
new file mode 100644
index 00000000..44d6e069
--- /dev/null
+++ b/public/javascripts/schema_browser/main.js
@@ -0,0 +1,558 @@
+/*
+ WWW SQL Designer, (C) 2005 Ondra Zara, o.z.fw@seznam.cz
+
+ This file is part of WWW SQL Designer.
+
+ WWW SQL Designer 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.
+
+ WWW SQL Designer 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 WWW SQL Designer; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+var drag_lock = 0; /* hybeme-li tabulkou */
+var new_table_flag = 0; /* cekame-li na click pro vytvoreni nove tabulky */
+var new_table_name = ""; /* jak se bude nova jmenovat */
+var table_array = Array(); /* ukazatele na tabulky */
+var relation_array = Array(); /* ukazatele na relace */
+var drag_start; /* prvni element dragu */
+var rel_hover_lock = -1; /* mame zvyraznenou relaci */
+var mouse_x,mouse_y; /* souradnice */
+var table_admin, row_admin, io_admin; /* tooly na baru */
+
+/* --------------------------------------------------------------------------- */
+
+function renumber_indexes(limit) {
+ var zIndex;
+ for (var i=0;i limit) table_array[i]._div.style.zIndex = zIndex-1;
+ }
+}
+
+function get_max_zIndex() {
+ var max_zIndex = 0;
+ var zIndex;
+ for (var i=0;i max_zIndex) max_zIndex = zIndex;
+ }
+ }
+ return max_zIndex;
+}
+
+function raise_table(number) {
+ row_admin.manageTable(table_array[number]);
+ table_admin.manageTable(table_array[number]);
+ for (var i=0;i bude posun
+ */
+ var rel;
+ var src = universalSource(co);
+ var index = drag_start.getAttribute("parent_number");
+ if (index != null) {
+ var moving_elm = table_array[index]._div;
+ var new_x = parseInt(moving_elm.style.left) + (co.clientX - mouse_x);
+ var new_y = parseInt(moving_elm.style.top) + (co.clientY - mouse_y);
+ table_array[index].moveTo(new_x,new_y);
+ table_array[index].updateMini();
+ mouse_x = co.clientX;
+ mouse_y = co.clientY;
+ } else {
+ /* necim hybeme, ale nema to parent number -> tak je to mapa */
+ var moving_elm = document.getElementById("map_");
+ var offs_x = co.clientX - mouse_x;
+ var offs_y = co.clientY - mouse_y;
+ var coef = DESK_SIZE / MAP_SIZE;
+ window.scrollBy(coef * offs_x, coef * offs_y);
+ mouse_x = co.clientX;
+ mouse_y = co.clientY;
+ update_map_();
+ }
+ }
+}
+
+function global_event_resize(co) {
+ update_map_();
+ update_bar();
+}
+
+function global_event_scroll(co) {
+ update_map_();
+ update_bar();
+}
+
+/* ------------------------------------------------------------------------------------ */
+
+function get_target_tablerow(x, y) {
+ var table=-1;
+ var row=-1;
+ var table_left, table_top, table_width, table_height;
+ var row_left, row_top, row_width, row_height;
+ /*
+ pro dane souradnice vratime odpovidajici tabulku a radku. -1 pokud nee.
+ */
+ for (var i=0;i table_left && x < table_left + table_width && y > table_top && y < table_top + table_height) {
+ table = i;
+ }
+ for (var j=0;j row_left && x < row_left + row_width && y > row_top && y < row_top + row_height) {
+ row = j;
+ }
+ } /* if not null */
+ } /* for vsecky radky */
+ } /* if not null */
+ } /* for vsechny tabulky */
+ return [table,row];
+}
+
+function add_table(x,y,title,custom_index) {
+ var count = get_free_index(table_array);
+ if (custom_index) {
+ count = custom_index;
+ }
+ var max_zIndex = get_max_zIndex();
+ var root=document.getElementById("root"); /* sem tabulku napojime */
+ var table = new Table(x,y,count,max_zIndex+1,title); /* to je ona */
+ table_array[count] = table; /* dame si objekt do pole */
+ root.appendChild(table._div); /* a pridame i do HTML stromu */
+ table.updateMini();
+ raise_table(count);
+
+ var bar = document.getElementById("bar");
+ bar.style.zIndex = max_zIndex+2;
+ var map = document.getElementById("map");
+ map.style.zIndex = max_zIndex+2;
+ return table;
+}
+
+function remove_table(index,no_animation) {
+ for (var i=0;i avail_width) {
+ actual_x = 10;
+ actual_y += 10 + max_height;
+ max_height = 0;
+ }
+ table_array[i].moveTo(actual_x,actual_y);
+ actual_x += 10 + table_width;
+ if (table_height > max_height) {
+ max_height = table_height;
+ }
+ }
+ }
+
+ for (var j=0;j je-li vybrano
+ _title => html element
+ _div => html element
+*/
+
+
+String.prototype.replaceAll = function ( strTarget, strSubString )
+{
+ var strText = this;
+ var intIndexOfMatch = strText.indexOf( strTarget );
+
+
+ while (intIndexOfMatch != -1)
+ {
+ strText = strText.replace( strTarget, strSubString )
+
+ intIndexOfMatch = strText.indexOf( strTarget );
+ }
+
+ return( strText );
+}
+
+
+/********** CODE BEGIN **********/
+
+function moveit(obj, x, y){
+ obj.style.left=parseInt(obj.style.left)+x+"px";
+ obj.style.top=parseInt(obj.style.top)+y+"px";
+}
+
+function print_view() {
+ var elem;
+ elem = document.getElementById("bar");
+ elem.parentNode.removeChild(elem);
+ elem = document.getElementById("map");
+ elem.parentNode.removeChild(elem);
+ elem = document.getElementById("root").getElementsByTagName("DIV");
+
+ for(var i = 0; i < elem.length; i++) {
+ moveit(elem[i], 0, -100);
+ }
+}
+
+/********** CODE END **********/
+
+function abstractParent_setTitle(text) {
+ this._title.innerHTML = text;
+}
+
+function abstractParent_destroy() {
+ this._div.parentNode.removeChild(this._div);
+ if (this._mini) {
+ this._mini.parentNode.removeChild(this._mini);
+ }
+}
+
+function abstractParent_select() {
+ if (this.selected) { return; }
+ this._div.className = this._div.className + " " + this._div.className + "_selected";
+ this.selected = true;
+}
+
+function abstractParent_deselect() {
+ this._div.className = this._div.getAttribute("defaultClassName");
+ this.selected = false;
+}
+
+function abstractParent(type, parent_number, row_number, className) {
+ this._div = document.createElement("div");
+ this._title = document.createElement("div");
+
+ this._title.className = "title";
+ this._div.className = className;
+
+ this._div.setAttribute("defaultClassName",className);
+ this._div.setAttribute("parent_number",parent_number);
+ this._div.setAttribute("row_number",row_number);
+ this._div.setAttribute("element_type",type);
+
+ this._title.setAttribute("parent_number",parent_number);
+ this._title.setAttribute("row_number",row_number);
+ this._title.setAttribute("element_type",TYPE_TITLE);
+
+ this._div.appendChild(this._title);
+
+ this.selected = false;
+ this.select = abstractParent_select;
+ this.deselect = abstractParent_deselect;
+ this.destroy = abstractParent_destroy;
+ this.setTitle = abstractParent_setTitle;
+/* universalAttacher(this._div,"mousedown",global_event_mousedown); */
+}
+
+/*
+ objekt Row
+ setPK(), losePK() - primary key
+ setFK(), loseFK() - foreign key
+ setIndex(), loseIndex() - index
+ setNN(), loseNN() - not null
+ setDef() - default
+ updateTitle() - updatne title="xxx" atribut
+ setTitle() - updatne title="xxx" atribut
+ setType() - updatne typ a defaultni hodnotu
+ updateSpecial() - updatne special
+ updateColor() - updatne pozadi dle datoveho typu
+ _special - drzadlo na specialni PK a FK, vpravo
+
+ pk - je-li primary key
+ fk - je-li foreign key
+ index - je-li index
+ nn - je-li notnull
+ def - defaultni hodnota
+ type - datovy typ (resp. jeho index)
+ spec - delka ci vycet
+*/
+
+function Row_setPK() {
+ this.pk = 1;
+ this.setIndex();
+ this.updateTitle();
+ this.updateSpecial();
+ this._title.style.fontWeight = "bold";
+}
+
+function Row_losePK() {
+ this.pk = 0;
+ this.updateTitle();
+ this.updateSpecial();
+ this._title.style.fontWeight = "normal";
+}
+
+function Row_setFK() {
+ this.fk = 1;
+ this.updateTitle();
+ this.updateSpecial();
+}
+
+function Row_loseFK() {
+ this.fk = 0;
+ this.updateTitle();
+ this.updateSpecial();
+}
+
+function Row_setNN() {
+ this.nn = 1;
+ this.updateTitle();
+}
+
+function Row_loseNN() {
+ this.nn = 0;
+ this.updateTitle();
+}
+
+function Row_setIndex() {
+ this.index = 1;
+ this.updateTitle();
+ this._title.style.fontStyle = "italic";
+}
+
+function Row_loseIndex() {
+ this.index = 0;
+ this.updateTitle();
+ this._title.style.fontStyle = "normal";
+}
+
+function Row_updateTitle() {
+ str = this._title.innerHTML + ": ";
+ str += SQL_TYPES_DEFAULT[this.type];
+ if (SQL_TYPES_SPEC[this.type]) {
+ str += "(" + this.spec + ")";
+ }
+ str += ", default: '" + this.def + "'";
+ if (this.pk) {
+ str += ", Primary key";
+ }
+ if (this.fk) {
+ str += ", Foreign key";
+ }
+ if (this.nn) {
+ str += ", NOT NULL";
+ }
+ if (this.index) {
+ str += ", Index";
+ }
+ this._div.setAttribute("title",str);
+ this._title.setAttribute("title",str);
+}
+
+function Row_setDef(value) {
+ this.def = value;
+ this.updateTitle();
+}
+
+function Row_setSpec(value) {
+ this.spec = value;
+ this.updateTitle();
+}
+
+function Row_setType(type) {
+ this.type = type;
+ this.def = SQL_TYPES_VALUES[type];
+ this.updateTitle();
+ this.updateColor();
+}
+
+function Row_updateSpecial() {
+ var str = "";
+ if (this.pk) str += "PK";
+ if (this.pk && this.fk) str += ",";
+ if (this.fk) str += "FK";
+ this._special.innerHTML = str;
+}
+
+function Row_updateColor() {
+ var total = 0;
+ for (var i=0;i0){
+ for(i=0;i right_2 ? top_table_1 + top_row_1 : top_table_2 + top_row_2);
+ end_x = Math.min(right_1, right_2) - RELATION_THICKNESS;
+ end_y = (right_1 < right_2 ? top_table_1 + top_row_1 : top_table_2 + top_row_2);
+ center_x = start_x + RELATION_OFFSET;
+ /* korekce kvuli borderu... */
+ start_x--;
+ end_x--;
+ }
+ }
+
+ /* a jedem */
+ this.elem_1.style.left = Math.min(start_x, center_x) + "px";
+ this.elem_1.style.top = start_y + "px"
+ this.elem_1.style.width = Math.abs(center_x - start_x) + "px";
+ this.elem_2.style.left = center_x;
+ this.elem_2.style.top = Math.min(start_y, end_y);
+ this.elem_2.style.height = Math.abs(end_y - start_y) + RELATION_THICKNESS + "px";
+ this.elem_3.style.left = Math.min(center_x, end_x) + "px";
+ this.elem_3.style.top = end_y + "px"
+ this.elem_3.style.width = Math.abs(center_x - end_x) + "px";
+
+ this.elem_4.style.top = parseInt(Math.min(start_y, end_y) + parseInt((Math.abs(end_y - start_y) + RELATION_THICKNESS) / 2)) - 5 + "px";
+ this.elem_4.style.left= center_x - 5 + "px";
+
+ var real_1_top = this.parent_1._div.offsetTop + this.row_1._div.offsetTop;
+ var real_2_top = this.parent_2._div.offsetTop + this.row_2._div.offsetTop;
+ var real_1_left = this.parent_1._div.offsetLeft;
+ var real_2_left = this.parent_2._div.offsetLeft;
+
+ var alignment = 1; // horizontal
+ if (Math.abs(end_y - start_y) + RELATION_THICKNESS <= 11 ){
+ alignment = 2; // vertical
+ }
+
+ var imgsrc = '';
+ switch (true){
+ case ( (real_1_top <= real_2_top) && (real_1_left <= real_2_left)): // top left
+ imgsrc = (alignment>1 ? 'v_1-n' : 'h_1-n');
+ break;
+ case ( (real_1_top <= real_2_top) && (real_1_left > real_2_left)): // top right
+ imgsrc = (alignment>1 ? 'v_n-1' : 'h_1-n');
+ break;
+ case ( (real_1_top >= real_2_top) && (real_1_left <= real_2_left)): // bottom left
+ imgsrc = (alignment>1 ? 'v_1-n' : 'h_n-1');
+ break;
+ case ( (real_1_top >= real_2_top) && (real_1_left >= real_2_left)): // bottom right
+ imgsrc = (alignment>1 ? 'v_n-1' : 'h_n-1');
+ break;
+ }
+ var eri = this.elem_4.getElementsByTagName('img');
+ eri[0].setAttribute("src","/images/schema_browser/"+imgsrc+".gif");
+}
+
+Relation.prototype = new abstractParent();
+function Relation(parent_1, row_1, parent_2, row_2, id) {
+ this.base = abstractParent;
+ this.base(TYPE_RELATION, id, row_1, "relation");
+ this._title.parentNode.removeChild(this._title);
+ this.update = Relation_update; /* funkce na aktualizaci car */
+ this.show = Relation_show; /* ukazani */
+ this.hide = Relation_hide; /* schovani */
+ this.activate = Relation_activate;
+ this.deactivate = Relation_deactivate;
+ this.parent_1 = parent_1; /* prvni rodicovska tabulka */
+ this.parent_2 = parent_2; /* druha rodicovska tabulka */
+ this.row_1 = row_1; /* prvni rodicovska radka */
+ this.row_2 = row_2; /* druha rodicovska radka */
+ this.elem_1 = document.createElement("div");
+ this.elem_2 = document.createElement("div");
+ this.elem_3 = document.createElement("div");
+ this.elem_1.style.height = RELATION_THICKNESS;
+ this.elem_2.style.width = RELATION_THICKNESS;
+ this.elem_3.style.height = RELATION_THICKNESS;
+ this.elem_1.setAttribute("element_type",TYPE_RELATION_PART);
+ this.elem_2.setAttribute("element_type",TYPE_RELATION_PART);
+ this.elem_3.setAttribute("element_type",TYPE_RELATION_PART);
+ this._div.appendChild(this.elem_1);
+ this._div.appendChild(this.elem_2);
+ this._div.appendChild(this.elem_3);
+
+ this.e_relation = document.createElement("img");
+ this.e_relation.setAttribute("src","/images/schema_browser/move_cross.gif");
+ this.e_relation.setAttribute("width","11");
+ this.e_relation.setAttribute("height","11");
+
+ this.elem_4 = document.createElement("div");
+ this.elem_4.setAttribute("width","11");
+ this.elem_4.setAttribute("height","11");
+ this.elem_4.setAttribute("element_type",TYPE_RELATION_PART);
+ this.elem_4.style.backgroundColor = 'white';
+ this.elem_4.appendChild(this.e_relation);
+ this._div.appendChild(this.elem_4);
+}
+
+/*
+ objekt Table:
+ moveTo() - posun na zadane souradnice
+ addRow() - prida radku
+ removeRow() - odebere radku
+ selectRow() - vybere radku
+ appendRelation() - prida relaci
+ removeRelation() - zrusi relaci
+ updateWidth() - aktualizuje sirku
+ updateMini() - aktualizuje minimapku
+ updateShadow() - aktualizuje rozbite stiny
+ showRelations() - ukaze relevantni relace
+ hideRelations() - schova relevantni relace
+ rows => pole radku
+ _rows => html drzak radku
+ relations => pole relaci, ktere se tykaji teto tabulky
+*/
+
+
+
+function Table_updateMini() {
+ var w = parseInt(this._div.offsetWidth);
+ var h = parseInt(this._div.offsetHeight);
+ var l = parseInt(this._div.style.left);
+ var t = parseInt(this._div.style.top);
+ this._mini.style.width = Math.round(w * MAP_SIZE / DESK_SIZE) + "px";
+ this._mini.style.height = Math.round(h * MAP_SIZE / DESK_SIZE) + "px";
+ this._mini.style.left = Math.round(l * MAP_SIZE / DESK_SIZE) + "px";
+ this._mini.style.top = Math.round(t * MAP_SIZE / DESK_SIZE) + "px";
+}
+
+function Table_moveTo(x,y) {
+ this._div.style.left = x + "px";
+ this._div.style.top = y + "px";
+ this.updateMini();
+}
+
+function Table_addRow(title,type,custom_index) {
+ var count = get_free_index(this.rows);
+ if (custom_index) {
+ count = custom_index;
+ }
+ var row = new Row(this.number,count,title,type); /* to je ona */
+ this.rows[count] = row; /* dame si objekt do pole */
+ this._rows.appendChild(row._div); /* a pridame i do HTML stromu */
+ this.updateWidth();
+ var x = this;
+ var endFuncRef = function() {
+ x.updateMini();
+ x.updateShadow();
+ for (var i=0;i max) {
+ max = this.rows[i]._title.innerHTML.length;
+ }
+ }
+ }
+ var new_ = Math.max(TABLE_WIDTH,80+max*LETTER_WIDTH);
+ this._div.style.width = new_ + "px";
+ if (new_ != orig) {
+ this.updateMini();
+ /* pokud jsme tabulce zmenili rozmery, musime aktualizovat relace */
+ for (var i=0;i|<\/html>||<\/body>/g,"");
+ } else {
+ alert("Ooops - no XML parser available");
+ }
+}
+
+
+
+function IOAdmin_go() {
+ switch (this._select.value) {
+ case "xml_in": /* import xml */
+ io_show(true);
+ break;
+
+ case "xml_out": /* export xml */
+ io_show(false);
+ var data = export_xml();
+ var area = document.getElementById("area");
+ area.value = data;
+ area.select();
+ break;
+
+ case "db_in": /* load from db */
+ var key = prompt("Keyword:","");
+ if (!key) return;
+ this._key = key;
+ document.location.href = "index.php?keyword="+encodeURIComponent(key);
+ //ajax_command(GET,"io.php?import=import&key="+encodeURIComponent(key),function(){return true},import_xml);
+ break;
+
+ case "db_out": /* save do db */
+
+ if(!this._key)
+ var key = prompt("Keyword:","");
+ else
+ var key = this._key;
+
+ if (!key) return;
+ var in_ref = function() {
+ var out = "";
+ out += "key="+encodeURIComponent(key);
+ out += "&data="+encodeURIComponent(export_xml());
+ return out;
+ }
+ var out_ref = function(data) {
+ alert("Data stored, keyword='"+key+"'");
+ }
+ ajax_command(POST,"io.php",in_ref,out_ref);
+ break;
+
+ case "db_out_as": /* save do db */
+ var key = prompt("Keyword:","");
+ if (!key) return;
+ var in_ref = function() {
+ var out = "";
+ out += "key="+encodeURIComponent(key);
+ out += "&data="+encodeURIComponent(export_xml());
+ return out;
+ }
+ var out_ref = function(data) {
+ alert("Data stored, keyword='"+key+"'");
+ }
+
+ this._key = key;
+ ajax_command(POST,"io.php",in_ref,out_ref);
+ break;
+
+ /********** CODE BEGIN **********/
+
+ case "show_keywords": /* Show keywords */
+ var out_ref = function(data) {
+ io_show(false);
+ var area = document.getElementById("area");
+ area.value = data;
+ }
+ ajax_command(GET,"io.php?show=show",function(){return ""},out_ref);
+ break;
+
+ case "print_view": /* Open print view */
+ print_view();
+ break;
+
+ /********** CODE END **********/
+
+ case "mysql": /* xslt to mysql */
+ io_show(false);
+ var data = export_xml();
+ data = apply_xslt(data,"xml2mysql.xsl");
+ var area = document.getElementById("area");
+ area.value = data;
+ area.select();
+ break;
+
+ case "mssql": /* xslt to mssql */
+ io_show(false);
+ var data = export_xml();
+ data = apply_xslt(data,"xml2mssql.xsl");
+ var area = document.getElementById("area");
+ area.value = data;
+ area.select();
+ break;
+
+ case "postgresql": /* xslt to mssql */
+ io_show(false);
+ var data = export_xml();
+ data = apply_xslt(data,"xml2postgresql.xsl");
+ var area = document.getElementById("area");
+ area.value = data;
+ area.select();
+ break;
+
+ case "sqlite": /* xslt to SQLite */
+ io_show(false);
+ var data = export_xml();
+ data = apply_xslt(data,"xml2sqlite.xsl");
+ var area = document.getElementById("area");
+ area.value = data;
+ area.select();
+ break;
+
+ case "symfony": /* xslt to Symfony YML */
+ io_show(false);
+ var data = export_xml();
+ data = apply_xslt(data,"xml2symfony.xsl");
+ var area = document.getElementById("area");
+ area.value = data;
+ area.select();
+ break;
+
+ case "propel": /* xslt to propel */
+ io_show(false);
+ var data = export_xml();
+ data = apply_xslt(data,"xml2propel.xsl");
+ var area = document.getElementById("area");
+ data = data.replaceAll("<","<");
+ data = data.replaceAll(">",">\r\n");
+ area.value = data;
+ area.select();
+ break;
+
+ case "oci": /* xslt to oci */
+ io_show(false);
+ var data = export_xml();
+ data = apply_xslt(data,"xml2oracle.xsl");
+ var area = document.getElementById("area");
+ area.value = data;
+ area.select();
+ break;
+
+ case "db_import": /* get schema from real database */
+ ajax_command(GET,"import.php",function(){return true},import_xml);
+ break;
+
+ } /* switch */
+}
+
+function IOAdmin_load() {
+ var area = document.getElementById("area");
+ var data = area.value;
+ import_xml(data);
+ var io = document.getElementById("io");
+ io.style.display = "none";
+ area.value = "";
+}
+
+function IOAdmin() {
+
+ this.go = IOAdmin_go;
+ this.load = IOAdmin_load;
+
+ this._div = document.getElementById("io_admin"); /* cela cast baru pro tabulky */
+ this._button = document.getElementById("io_button");
+ this._settingsbutton = document.getElementById("io_settings_button");
+ this._select = document.getElementById("io_select");
+ this._import = document.getElementById("import");
+
+ this._div.setAttribute("element_type",TYPE_BAR);
+ this._button.setAttribute("element_type",TYPE_BAR);
+ this._settingsbutton.setAttribute("element_type",TYPE_BAR);
+ this._select.setAttribute("element_type",TYPE_BAR);
+ this._import.setAttribute("element_type",TYPE_BAR);
+
+ var tmp = document.getElementById("close");
+ tmp.setAttribute("element_type",TYPE_BAR);
+ tmp = document.getElementById("io");
+ tmp.setAttribute("element_type",TYPE_BAR);
+ tmp = document.getElementById("area");
+ tmp.setAttribute("element_type",TYPE_BAR);
+
+ universalAttacher(this._button,"click",getLateFunc(this,"go"));
+/* universalAttacher(this._settingsbutton,"click",getLateFunc(this,"exp")); */
+ universalAttacher(this._import,"click",getLateFunc(this,"load"));
+}
diff --git a/public/javascripts/schema_browser/settings.js b/public/javascripts/schema_browser/settings.js
new file mode 100644
index 00000000..49ec920f
--- /dev/null
+++ b/public/javascripts/schema_browser/settings.js
@@ -0,0 +1,30 @@
+/*
+ WWW SQL Designer, (C) 2005 Ondra Zara, o.z.fw@seznam.cz
+
+ This file is part of WWW SQL Designer.
+
+ WWW SQL Designer 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.
+
+ WWW SQL Designer 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 WWW SQL Designer; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+var DELAY = 10; /* pauza mezi rostouci animaci */
+var BAR_HEIGHT = 100;
+
+var TYPE_TABLE = 0;
+var TYPE_TITLE = 1;
+var TYPE_ROW = 2;
+var TYPE_ROWTITLE = 3;
+var TYPE_RELATION = 4;
+var TYPE_RELATION_PART = 5; /* not used */
+var TYPE_BAR = 6;
+var TYPE_MAP = 7;
diff --git a/public/javascripts/schema_browser/sql_types.js b/public/javascripts/schema_browser/sql_types.js
new file mode 100644
index 00000000..fd667e53
--- /dev/null
+++ b/public/javascripts/schema_browser/sql_types.js
@@ -0,0 +1,134 @@
+/*
+ WWW SQL Designer, (C) 2005 Ondra Zara, o.z.fw@seznam.cz
+
+ This file is part of WWW SQL Designer.
+
+ WWW SQL Designer 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.
+
+ WWW SQL Designer 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 WWW SQL Designer; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/* -------------------------- nase obecne datove typy -------------------------- */
+
+var SQL_TYPES_DIVISION = [
+ {color:"rgb(238,238,170)",name:"Numeric",count:5},
+ {color:"rgb(255,200,200)",name:"Character",count:5},
+ {color:"rgb(200,255,200)",name:"Date & Time",count:4},
+ {color:"rgb(200,200,255)",name:"Others",count:2}
+];
+
+var SQL_TYPES_DEFAULT = [
+ "Integer", /* 0 */
+ "Byte", /* 1 */
+ "Decimal", /* 2 */
+ "Single precision", /* 3 */
+ "Double precision", /* 4 */
+ "Char", /* 5 */
+ "String", /* 6 */
+ "Text", /* 7 */
+ "Binary", /* 8 */
+ "BLOB", /* 9 */
+ "Date", /*10 */
+ "Time", /*11 */
+ "Datetime", /*12 */
+ "Timestamp", /*13 */
+ "Enum", /*14 */
+ "Set" /*15 */
+];
+
+var SQL_TYPES_VALUES = [
+ /* defaultni hodnoty */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ "",
+ "",
+ "",
+ "",
+ "",
+ "1900-01-01",
+ "00:00:00",
+ "1900-01-01 00:00:00",
+ 0,
+ "",
+ ""
+];
+
+var SQL_TYPES_SPEC = [
+ /* potrebuji-li doplnkovy inputbox */
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 1,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1
+];
+
+/* --------------------------- jejich ekvivalenty v sql ------------------------- */
+
+var SQL_TYPES_MYSQL = [
+ "INTEGER", /* 0 */
+ "TINYINT", /* 1 */
+ "FLOAT", /* 2 */
+ "DOUBLE", /* 3 */
+ "CHAR", /* 4 */
+ "MEDIUMTEXT", /* 5 */
+ "VARBINARY", /* 6 */
+ "BLOB", /* 7 */
+ "DATE", /* 8 */
+ "TIME", /* 9 */
+ "DATETIME", /* 10 */
+ "TIMESTAMP", /* 11 */
+ "ENUM", /* 12 */
+ "SET", /* 13 */
+];
+
+/* --------------------------- fallback pro zname i nezname typy ------------------- */
+
+var SQL_FALLBACK_MYSQL = new Object();
+ SQL_FALLBACK_MYSQL["CHAR"] = 4;
+ SQL_FALLBACK_MYSQL["VARCHAR"] = 4;
+ SQL_FALLBACK_MYSQL["TINYTEXT"] = 5;
+ SQL_FALLBACK_MYSQL["TEXT"] = 5;
+ SQL_FALLBACK_MYSQL["BLOB"] = 7;
+ SQL_FALLBACK_MYSQL["MEDIUMTEXT"] = 5;
+ SQL_FALLBACK_MYSQL["MEDIUMBLOB"] = 7;
+ SQL_FALLBACK_MYSQL["LONGTEXT"] = 5;
+ SQL_FALLBACK_MYSQL["LONGBLOB"] = 7;
+ SQL_FALLBACK_MYSQL["TINYINT"] = 1;
+ SQL_FALLBACK_MYSQL["SMALLINT"] = 0;
+ SQL_FALLBACK_MYSQL["MEDIUMINT"] = 0;
+ SQL_FALLBACK_MYSQL["INT"] = 0;
+ SQL_FALLBACK_MYSQL["INTEGER"] = 0;
+ SQL_FALLBACK_MYSQL["BIGINT"] = 0;
+ SQL_FALLBACK_MYSQL["FLOAT"] = 2;
+ SQL_FALLBACK_MYSQL["DOUBLE"] = 3;
+ SQL_FALLBACK_MYSQL["DECIMAL"] = 3;
+ SQL_FALLBACK_MYSQL["DATE"] = 8;
+ SQL_FALLBACK_MYSQL["TIME"] = 9;
+ SQL_FALLBACK_MYSQL["DATETIME"] = 10;
+ SQL_FALLBACK_MYSQL["TIMESTAMP"] = 11;
+ SQL_FALLBACK_MYSQL["ENUM"] = 12;
+ SQL_FALLBACK_MYSQL["SET"] = 13;
diff --git a/public/javascripts/schema_browser/style.js b/public/javascripts/schema_browser/style.js
new file mode 100644
index 00000000..d8b19c88
--- /dev/null
+++ b/public/javascripts/schema_browser/style.js
@@ -0,0 +1,10 @@
+var RELATION_THICKNESS = 1;
+var RELATION_OFFSET = 10;
+var ROW_HEIGHT = 20;
+var TABLE_WIDTH = 130;
+var LETTER_WIDTH = 8;
+var BUTTON_ENABLED = "#000";
+var BUTTON_DISABLED = "#888";
+
+var DESK_SIZE = 2000;
+var MAP_SIZE = 100;
diff --git a/public/stylesheets/schema_browser/bar.css b/public/stylesheets/schema_browser/bar.css
new file mode 100644
index 00000000..0c899aed
--- /dev/null
+++ b/public/stylesheets/schema_browser/bar.css
@@ -0,0 +1,271 @@
+/* ---------------------------------- elementy na panelu ------------------------------- */
+.button {
+ width: 100px;
+ height: 12px;
+ border: 1px solid #000;
+ background-color: #aaa;
+ text-align: center;
+ padding-top: 2px;
+ cursor: pointer;
+}
+
+div.button:hover {
+ background-color: #aac;
+}
+
+
+/* TABLE */
+
+#table_admin {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ height: 100%;
+ width: 250px;
+ font-size: x-small;
+ border-right: 2px solid #ddd;
+ _font-size: xx-small;
+}
+
+#table_add_button {
+ position: absolute;
+ left: 10px;
+ top: 55px;
+}
+
+#table_del_button {
+ position: absolute;
+ left: 130px;
+ top: 55px;
+}
+
+#table_move_button {
+ position: absolute;
+ left: 10px;
+ top: 75px;
+}
+
+#table_clear_button {
+ position: absolute;
+ left: 130px;
+ top: 75px;
+}
+
+#table_name {
+ font-size: x-small;
+ _font-size: xx-small;
+ position: absolute;
+ left:52px;
+ top: 25px;
+ width: 180px;
+}
+
+#table_admin_label {
+ text-align: left;
+ font-size: medium;
+ font-weight: bold;
+}
+
+#table_name_label {
+ font-size: small;
+ position: absolute;
+ top: 27px;
+ left: 10px;
+}
+
+/* ROW */
+
+#row_admin {
+ position: absolute;
+ left: 255px;
+ top: 0px;
+ height: 100%;
+ width: 300px;
+ font-size: x-small;
+ border-right: 2px solid #ddd;
+ _font-size: xx-small;
+}
+
+#row_add_button {
+ position: absolute;
+ left: 10px;
+ top: 60px;
+}
+
+#row_del_button {
+ position: absolute;
+ left: 120px;
+ top: 60px;
+}
+
+#row_up_button {
+ position: absolute;
+ left: 10px;
+ top: 80px;
+ width: 60px;
+}
+
+#row_down_button {
+ position: absolute;
+ left: 80px;
+ top: 80px;
+ width: 60px;
+}
+
+#row_name {
+ font-size: x-small;
+ _font-size: xx-small;
+ position: absolute;
+ left:52px;
+ top: 1px;
+ width: 180px;
+}
+
+#row_admin_label {
+ text-align: right;
+ font-size: medium;
+ font-weight: bold;
+ padding-right: 2px;
+}
+
+#row_name_label {
+ font-size: small;
+ position: absolute;
+ top: 4px;
+ left: 10px;
+}
+
+#row_primary {
+ position: absolute;
+ top: 80px;
+ left: 185px;
+}
+
+#row_primary_label {
+ position: absolute;
+ top: 83px;
+ left: 205px;
+}
+
+#row_index {
+ position: absolute;
+ top: 80px;
+ left: 220px;
+}
+
+#row_index_label {
+ position: absolute;
+ top: 83px;
+ left: 240px;
+}
+
+#row_notnull {
+ position: absolute;
+ top: 80px;
+ left: 260px;
+}
+
+#row_notnull_label {
+ position: absolute;
+ top: 83px;
+ left: 280px;
+}
+
+#row_type {
+ font-size: x-small;
+ _font-size: xx-small;
+ position: absolute;
+ top: 20px;
+ left: 52px;
+}
+
+#row_type_label {
+ font-size: small;
+ position: absolute;
+ top: 23px;
+ left: 10px;
+}
+
+#row_default {
+ font-size: x-small;
+ _font-size: xx-small;
+ position: absolute;
+ top: 40px;
+ left: 80px;
+}
+
+#row_default_label {
+ font-size: small;
+ position: absolute;
+ top: 42px;
+ left: 10px;
+}
+
+#row_spec_1 {
+ font-size: small;
+ position: absolute;
+ top: 22px;
+ left: 200px;
+}
+
+#row_spec_2 {
+ font-size: small;
+ position: absolute;
+ top: 22px;
+ left: 258px;
+}
+
+#row_spec {
+ font-size: x-small;
+ _font-size: xx-small;
+ position: absolute;
+ top: 20px;
+ left: 208px;
+ width: 50px;
+}
+
+
+/* IO */
+
+#io_admin {
+ position: absolute;
+ left: 560px;
+ top: 0px;
+ height: 100%;
+ width: 220px;
+ font-size: x-small;
+ _font-size: xx-small;
+ border-right: 2px solid #ddd;
+}
+
+#io_button {
+ position: absolute;
+ left: 10px;
+ top: 55px;
+}
+
+#io_settings_button {
+ position: absolute;
+ left: 10px;
+ top: 75px;
+}
+
+#io_admin_label {
+ text-align: right;
+ font-size: medium;
+ font-weight: bold;
+}
+
+#io_select_label {
+ font-size: small;
+ position: absolute;
+ top: 29px;
+ left: 10px;
+}
+
+#io_select {
+ font-size: x-small;
+ position: absolute;
+ top: 27px;
+ left: 70px;
+}
diff --git a/public/stylesheets/schema_browser/foo b/public/stylesheets/schema_browser/foo
new file mode 100644
index 00000000..e69de29b
diff --git a/public/stylesheets/schema_browser/style.css b/public/stylesheets/schema_browser/style.css
new file mode 100644
index 00000000..9dea7819
--- /dev/null
+++ b/public/stylesheets/schema_browser/style.css
@@ -0,0 +1,192 @@
+@import url("/stylesheets/schema_browser/bar.css");
+/* ---------------------------------- spolecne deklarace ------------------------------- */
+
+body {
+ font-family: bitstream vera sans mono, monospace, courier new, verdana, sans serif;
+ font-size: small;
+ padding: 0px;
+ margin: 0px;
+ _font-size: x-small;
+ background: url('/stylesheets/schema_browser/foo') fixed; /* ie hack */
+}
+
+#root {
+ background-image: url("/images/schema_browser/back.gif");
+}
+
+#bar {
+ background-color: #ccc;
+ position: fixed;
+ _position: absolute;
+ _top:expression(eval(document.body.scrollTop));
+ _left:expression(eval(document.body.scrollLeft));
+}
+
+#shadow {
+ background-image: url("/images/schema_browser/shadow.png");
+ width: 100%;
+ height: 8px;
+ position: relative;
+ _background-image: none;
+}
+
+#map {
+ position: fixed;
+ right: 0px;
+ bottom: 0px;
+ _position:absolute;
+ _left:expression(eval(document.body.scrollLeft)+eval(document.body.clientWidth)-map.offsetWidth);
+ _top:expression(eval(document.body.scrollTop)+eval(document.body.clientHeight)-map.offsetHeight);
+ background-color: #fff;
+ border: 1px solid #000;
+}
+
+#map_ {
+ border: 2px solid #f00;
+ width: 0px;
+ height: 0px;
+ font-size: 1px;
+ position: absolute;
+}
+
+/* ---------------------------------- elementy na plose ------------------------------- */
+
+.table {
+ position: absolute;
+ _height: 20px;
+ min-height: 20px;
+ border: 1px solid #000;
+ background-color: #ddd;
+}
+
+.table_selected {
+ border: 2px solid #000;
+}
+
+.table_title {
+ text-align: center;
+ position: absolute;
+ left: 0px;
+ top: 1px;
+ width: 100%;
+ background-color: #ddd;
+}
+
+.rows {
+ margin-top: 20px;
+}
+
+.row {
+ padding-left: 3px;
+ padding-top: 2px;
+/* height: 20px; */
+ border-top: 1px dotted #888;
+ overflow: hidden;
+}
+
+.row .sipka {
+ display: none;
+ float: left;
+ color: #f00;
+ font-weight: bold;
+}
+
+.row_selected {
+}
+
+.row_selected .sipka {
+ display: inline;
+}
+
+.row_title {
+ text-align: left;
+}
+
+.row .special {
+ float: right;
+ margin-right: 2px;
+}
+
+.mini {
+ border: 1px solid #000;
+ background-color: #eea;
+ position: absolute;
+ font-size: 1px
+}
+
+.shadow_right {
+ background-image: url("/images/schema_browser/shadow_right.png");
+ width: 8px;
+ height: 100%;
+ position: absolute;
+ right: -9px;
+ top: 1px;
+ _background-image: none;
+}
+
+.shadow_bottom {
+ background-image: url("/images/schema_browser/shadow_bottom.png");
+ width: 100%;
+ height: 8px;
+ position: absolute;
+ bottom: -9px;
+ left: 1px;
+ _background-image: none;
+}
+
+.shadow_corner {
+ background-image: url("/images/schema_browser/shadow_corner.png");
+ width: 8px;
+ height: 8px;
+ position: absolute;
+ right: -9px;
+ bottom: -9px;
+ _background-image: none;
+}
+
+.relation div {
+ background-color: #000;
+ position: absolute;
+ font-size: 1px;
+ line-height: 0px;
+}
+
+
+#io {
+ display: none;
+ position: fixed;
+ left: 20px;
+ top: 20px;
+ width: 300px;
+ height: 300px;
+ z-index: 100;
+ background-color: #fff;
+ border: 2px solid #000;
+
+ _position: absolute;
+ _top:expression(eval(document.body.scrollTop)+20);
+ _left:expression(eval(document.body.scrollLeft)+20);
+}
+
+#area {
+ position: absolute;
+ left: 20px;
+ top: 8px;
+ width: 260px;
+ height: 260px;
+ margin: auto;
+ font-size: xx-small;
+}
+
+#io #close {
+ position: absolute;
+ left: 200px;
+ top: 270px;
+}
+
+#io #import {
+ position: absolute;
+ display: none;
+ left: 40px;
+ top: 270px;
+}