summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVeronika Irvine <veronika>2004-02-03 19:27:54 +0000
committerVeronika Irvine <veronika>2004-02-03 19:27:54 +0000
commita38b0e1c16db17f32238a4af0323e106634ade69 (patch)
tree28b54fec63d285b014126c480f25aea0f0f1e593
parentd81e473e483ae4fce965f43d47dd34220fc3e0cd (diff)
downloadeclipse.platform.swt-a38b0e1c16db17f32238a4af0323e106634ade69.tar.gz
eclipse.platform.swt-a38b0e1c16db17f32238a4af0323e106634ade69.tar.xz
eclipse.platform.swt-a38b0e1c16db17f32238a4af0323e106634ade69.zip
add setFont support to TableItem
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_gtk.xml11
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c12
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h3
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java3
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java31
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java63
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableItem.java46
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java5
8 files changed, 145 insertions, 29 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_gtk.xml b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_gtk.xml
index 08b1987f97..59abb839c5 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_gtk.xml
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_gtk.xml
@@ -23,6 +23,17 @@
<eclipse.refreshLocal resource="org.eclipse.swt.gtk" depth="infinite" />
</target>
+<target name="build_gtk_linux_swtlib" depends="init">
+ <exec dir="./bin/library" executable="sh">
+ <arg line="${basedir}/bin/library/build.sh"/>
+ <arg line="make_swt"/>
+ </exec>
+ <copy todir="${lib_destdir}">
+ <fileset dir="${basedir}/bin/library/" includes="*.so"/>
+ </copy>
+ <eclipse.refreshLocal resource="org.eclipse.swt.gtk" depth="infinite" />
+</target>
+
<target name="clean" depends="init">
<tstamp/>
<exec dir="./bin/library" executable="sh">
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
index d5c43bf0ab..19542b195e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
@@ -230,6 +230,18 @@ JNIEXPORT jint JNICALL OS_NATIVE(G_1TYPE_1STRING)
}
#endif
+#ifndef NO_PANGO_1TYPE_1FONT_1DESCRIPTION
+JNIEXPORT jint JNICALL OS_NATIVE(PANGO_1TYPE_1FONT_1DESCRIPTION)
+ (JNIEnv *env, jclass that)
+{
+ jint rc;
+ NATIVE_ENTER(env, that, "PANGO_1TYPE_1FONT_1DESCRIPTION\n")
+ rc = (jint)PANGO_TYPE_FONT_DESCRIPTION;
+ NATIVE_EXIT(env, that, "PANGO_1TYPE_1FONT_1DESCRIPTION\n")
+ return rc;
+}
+#endif
+
#ifndef NO_PANGO_1PIXELS
JNIEXPORT jint JNICALL OS_NATIVE(PANGO_1PIXELS)
(JNIEnv *env, jclass that, jint arg0)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h
index 181062b1f2..81528395d5 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h
@@ -24,12 +24,13 @@
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <pango/pango.h>
+#include <pango/pango-font.h>
#include <string.h>
#include <dlfcn.h>
#ifndef GDK_WINDOWING_X11
#define NO_XWindowChanges
-#defien NO_XDefaultScreen
+#define NO_XDefaultScreen
#define NO_XReconfigureWMWindow
#define NO_XSetInputFocus
#define NO_gdk_1x11_1drawable_1get_1xdisplay
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
index 8cacc0b863..1d198d3edc 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
@@ -311,7 +311,9 @@ public class OS {
/** Properties */
public static final byte[] background_gdk = signal("background-gdk");
public static final byte[] button_relief = signal("button_relief");
+ public static final byte[] cell_background_gdk = signal("cell-background-gdk");
public static final byte[] focus_line_width = signal("focus_line_width");
+ public static final byte[] font_desc = signal("font-desc");
public static final byte[] foreground_gdk = signal("foreground-gdk");
public static final byte[] horizontal_separator = signal("horizontal_separator");
public static final byte[] interior_focus = signal("interior_focus");
@@ -377,6 +379,7 @@ public static final synchronized native int G_TYPE_INT();
public static final synchronized native int G_TYPE_STRING();
public static final synchronized native int GtkTreeIter_sizeof();
public static final synchronized native int PANGO_PIXELS(int dimension);
+public static final synchronized native int PANGO_TYPE_FONT_DESCRIPTION();
public static final synchronized native int g_filename_to_utf8(int opsysstring, int len, int[] bytes_read, int[] bytes_written, int[] error);
public static final synchronized native int g_filename_to_uri(int filename, int hostname, int[] error);
public static final synchronized native int g_filename_from_utf8(int opsysstring, int len, int[] bytes_read, int[] bytes_written, int[] error);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
index 9e737643c6..25e3c87cac 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
@@ -157,8 +157,10 @@ public class Display extends Device {
int treeSelectionLength;
int treeSelectionProc;
Callback treeSelectionCallback;
- int cellDataProc;
- Callback cellDataCallback;
+ int textCellDataProc;
+ Callback textCellDataCallback;
+ int pixbufCellDataProc;
+ Callback pixbufCellDataCallback;
/* Drag Detect */
int dragStartX,dragStartY;
@@ -1443,9 +1445,13 @@ void initializeCallbacks () {
treeSelectionProc = treeSelectionCallback.getAddress();
if (treeSelectionProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
- cellDataCallback = new Callback (this, "cellDataProc", 5);
- cellDataProc = cellDataCallback.getAddress ();
- if (cellDataProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
+ textCellDataCallback = new Callback (this, "textCellDataProc", 5);
+ textCellDataProc = textCellDataCallback.getAddress ();
+ if (textCellDataProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
+
+ pixbufCellDataCallback = new Callback (this, "pixbufCellDataProc", 5);
+ pixbufCellDataProc = pixbufCellDataCallback.getAddress ();
+ if (pixbufCellDataProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
}
void initializeWidgetTable () {
@@ -1724,8 +1730,10 @@ void releaseDisplay () {
/* Dispose GtkTreeView callbacks */
treeSelectionCallback.dispose (); treeSelectionCallback = null;
treeSelectionProc = 0;
- cellDataCallback.dispose (); cellDataCallback = null;
- cellDataProc = 0;
+ textCellDataCallback.dispose (); textCellDataCallback = null;
+ textCellDataProc = 0;
+ pixbufCellDataCallback.dispose (); pixbufCellDataCallback = null;
+ pixbufCellDataProc = 0;
/* Dispose the caret callback */
if (caretId != 0) OS.gtk_timeout_remove (caretId);
@@ -2220,10 +2228,15 @@ int caretProc (int clientData) {
return 0;
}
-int cellDataProc (int tree_column, int cell, int tree_model, int iter, int data) {
+int pixbufCellDataProc (int tree_column, int cell, int tree_model, int iter, int data) {
+ Widget widget = getWidget (data);
+ if (widget == null) return 0;
+ return widget.pixbufCellDataProc (tree_column, cell, tree_model, iter, data);
+}
+int textCellDataProc (int tree_column, int cell, int tree_model, int iter, int data) {
Widget widget = getWidget (data);
if (widget == null) return 0;
- return widget.cellDataProc (tree_column, cell, tree_model, iter, data);
+ return widget.textCellDataProc (tree_column, cell, tree_model, iter, data);
}
int treeSelectionProc (int model, int path, int iter, int data) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
index 3896e0ab6d..a86764d1aa 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
@@ -53,7 +53,8 @@ public class Table extends Composite {
static final int GRAYED_COLUMN = 1;
static final int FOREGROUND_COLUMN = 2;
static final int BACKGROUND_COLUMN = 3;
- static final int FIRST_COLUMN = BACKGROUND_COLUMN + 1;
+ static final int FONT_COLUMN = 4;
+ static final int FIRST_COLUMN = FONT_COLUMN + 1;
/**
* Constructs a new instance of this class given its parent
@@ -136,8 +137,7 @@ public void addSelectionListener (SelectionListener listener) {
addListener (SWT.DefaultSelection,typedListener);
}
-int cellDataProc (int tree_column, int cell, int tree_model, int iter, int data) {
- int [] ptr = new int [1];
+int textCellDataProc (int tree_column, int cell, int tree_model, int iter, int data) {
int modelIndex = -1;
if (columnCount == 0) {
modelIndex = Table.FIRST_COLUMN;
@@ -150,6 +150,7 @@ int cellDataProc (int tree_column, int cell, int tree_model, int iter, int data)
}
}
if (modelIndex == -1) return 0;
+ int [] ptr = new int [1];
OS.gtk_tree_model_get (tree_model, iter, modelIndex + 2, ptr, -1); //foreground-gdk
if (ptr [0] != 0) {
OS.g_object_set(cell, OS.foreground_gdk, ptr[0], 0);
@@ -159,6 +160,31 @@ int cellDataProc (int tree_column, int cell, int tree_model, int iter, int data)
if (ptr [0] != 0) {
OS.g_object_set(cell, OS.background_gdk, ptr[0], 0);
}
+ ptr = new int [1];
+ OS.gtk_tree_model_get (tree_model, iter, modelIndex + 4, ptr, -1); //font-desc
+ if (ptr [0] != 0) {
+ OS.g_object_set(cell, OS.font_desc, ptr[0], 0);
+ }
+ return 0;
+}
+int pixbufCellDataProc (int tree_column, int cell, int tree_model, int iter, int data) {
+ int modelIndex = -1;
+ if (columnCount == 0) {
+ modelIndex = Table.FIRST_COLUMN;
+ } else {
+ for (int i = 0; i < columns.length; i++) {
+ if (columns [i] != null && columns [i].handle == tree_column) {
+ modelIndex = columns [i].modelIndex;
+ break;
+ }
+ }
+ }
+ if (modelIndex == -1) return 0;
+ int [] ptr = new int [1];
+ OS.gtk_tree_model_get (tree_model, iter, modelIndex + 3, ptr, -1); //cell-background-gdk
+ if (ptr [0] != 0) {
+ OS.g_object_set(cell, OS.cell_background_gdk, ptr[0], 0);
+ }
return 0;
}
@@ -186,11 +212,13 @@ void createHandle (int index) {
* 1 - grayed
* 2 - foreground for row
* 3 - background for row
- * 4 - pixbuf
- * 5 - text
- * 6 - foreground for cell
- * 7 - background for cell
- * 8 - ...
+ * 4 - font for row
+ * 5 - pixbuf for cell
+ * 6 - text for cell
+ * 7 - foreground for cell
+ * 8 - background for cell
+ * 9 - font for cell
+ * 10 - ...
*/
int [] types = getColumnTypes (1);
modelHandle = OS.gtk_list_store_newv (types.length, types);
@@ -228,7 +256,7 @@ void createColumn (TableColumn column, int index) {
boolean [] usedColumns = new boolean [modelLength];
for (int i=0; i<columnCount; i++) {
int columnIndex = columns [i].modelIndex;
- usedColumns [columnIndex] = usedColumns [columnIndex + 1] = usedColumns [columnIndex + 2] = usedColumns [columnIndex + 3] = true;
+ usedColumns [columnIndex] = usedColumns [columnIndex + 1] = usedColumns [columnIndex + 2] = usedColumns [columnIndex + 3] = usedColumns [columnIndex + 4] = true;
}
while (modelIndex < modelLength) {
if (!usedColumns [modelIndex]) break;
@@ -236,7 +264,7 @@ void createColumn (TableColumn column, int index) {
}
if (modelIndex == modelLength) {
int oldModel = modelHandle;
- int[] types = getColumnTypes (columnCount + 4);
+ int[] types = getColumnTypes (columnCount + 5);
int newModel = OS.gtk_list_store_newv (types.length, types);
if (newModel == 0) error (SWT.ERROR_NO_HANDLES);
int [] ptr = new int [1];
@@ -327,6 +355,7 @@ void createRenderers (int columnHandle, int modelIndex, boolean check, int colum
OS.gtk_tree_view_column_add_attribute (columnHandle, textRenderer, "text", modelIndex + 1);
OS.gtk_tree_view_column_add_attribute (columnHandle, textRenderer, "foreground-gdk", FOREGROUND_COLUMN);
OS.gtk_tree_view_column_add_attribute (columnHandle, textRenderer, "background-gdk", BACKGROUND_COLUMN);
+ OS.gtk_tree_view_column_add_attribute (columnHandle, textRenderer, "font-desc", FONT_COLUMN);
boolean customDraw = firstCustomDraw;
if (columnCount != 0) {
@@ -338,7 +367,8 @@ void createRenderers (int columnHandle, int modelIndex, boolean check, int colum
}
}
if (customDraw) {
- OS.gtk_tree_view_column_set_cell_data_func (columnHandle, textRenderer, display.cellDataProc, handle, 0);
+ OS.gtk_tree_view_column_set_cell_data_func (columnHandle, textRenderer, display.textCellDataProc, handle, 0);
+ OS.gtk_tree_view_column_set_cell_data_func (columnHandle, pixbufRenderer, display.pixbufCellDataProc, handle, 0);
}
}
@@ -550,6 +580,8 @@ void destroyItem (TableColumn column) {
OS.gtk_list_store_set (newModel, newItem, FIRST_COLUMN + 2, ptr [0], -1);
OS.gtk_tree_model_get (oldModel, oldItem, column.modelIndex + 3, ptr, -1); //background
OS.gtk_list_store_set (newModel, newItem, FIRST_COLUMN + 3, ptr [0], -1);
+ OS.gtk_tree_model_get (oldModel, oldItem, column.modelIndex + 4, ptr, -1); //font
+ OS.gtk_list_store_set (newModel, newItem, FIRST_COLUMN + 4, ptr [0], -1);
OS.gtk_list_store_remove (oldModel, oldItem);
OS.g_free (oldItem);
item.handle = newItem;
@@ -566,6 +598,7 @@ void destroyItem (TableColumn column) {
OS.gtk_list_store_set (modelHandle, item, modelIndex + 1, 0, -1); //text
OS.gtk_list_store_set (modelHandle, item, modelIndex + 2, 0, -1); //foreground
OS.gtk_list_store_set (modelHandle, item, modelIndex + 3, 0, -1); //background
+ OS.gtk_list_store_set (modelHandle, item, modelIndex + 4, 0, -1); //font
}
if (index == 0) {
TableColumn checkColumn = columns [0];
@@ -652,16 +685,18 @@ public int getColumnCount () {
}
int[] getColumnTypes (int n) {
- int[] types = new int [(n * 4) + FIRST_COLUMN];
+ int[] types = new int [(n * 5) + FIRST_COLUMN];
types [CHECKED_COLUMN] = OS.G_TYPE_BOOLEAN ();
types [GRAYED_COLUMN] = OS.G_TYPE_BOOLEAN ();
types [FOREGROUND_COLUMN] = OS.GDK_TYPE_COLOR ();
types [BACKGROUND_COLUMN] = OS.GDK_TYPE_COLOR ();
- for (int i=FIRST_COLUMN; i<types.length; i+=4) {
- types [i] = OS.GDK_TYPE_PIXBUF (); //image
+ types [FONT_COLUMN] = OS.PANGO_TYPE_FONT_DESCRIPTION ();
+ for (int i=FIRST_COLUMN; i<types.length; i+=5) {
+ types [i + 0] = OS.GDK_TYPE_PIXBUF (); //image
types [i + 1] = OS.G_TYPE_STRING (); //text
types [i + 2] = OS.GDK_TYPE_COLOR (); //foreground
types [i + 3] = OS.GDK_TYPE_COLOR (); //background
+ types [i + 4] = OS.PANGO_TYPE_FONT_DESCRIPTION (); //font
}
return types;
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableItem.java
index 172797fc70..c9e6c19540 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableItem.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableItem.java
@@ -556,9 +556,11 @@ public void setBackground (int index, Color color) {
if (!customDraw) {
int list = OS.gtk_tree_view_column_get_cell_renderers (column);
int length = OS.g_list_length (list);
- int renderer = OS.g_list_nth_data (list, length - 1);
+ int textRenderer = OS.g_list_nth_data (list, length - 1);
+ int pixbufRenderer = OS.g_list_nth_data (list, length - 2);
OS.g_list_free (list);
- OS.gtk_tree_view_column_set_cell_data_func (column, renderer, display.cellDataProc, parent.handle, 0);
+ OS.gtk_tree_view_column_set_cell_data_func (column, textRenderer, display.textCellDataProc, parent.handle, 0);
+ OS.gtk_tree_view_column_set_cell_data_func (column, pixbufRenderer, display.pixbufCellDataProc, parent.handle, 0);
if (parent.columnCount == 0) {
parent.firstCustomDraw = true;
} else {
@@ -604,6 +606,11 @@ public void setChecked (boolean checked) {
*/
public void setFont (Font font){
checkWidget ();
+ if (font != null && font.isDisposed ()) {
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int fontHandle = font != null ? font.handle : 0;
+ OS.gtk_list_store_set (parent.modelHandle, handle, Table.FONT_COLUMN, fontHandle, -1);
}
/**
@@ -627,6 +634,35 @@ public void setFont (Font font){
*/
public void setFont (int index, Font font) {
checkWidget ();
+ if (font != null && font.isDisposed ()) {
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int count = Math.max (1, parent.columnCount);
+ if (0 > index || index > count - 1) return;
+ int parentHandle = parent.handle;
+ int column = OS.gtk_tree_view_get_column (parentHandle, index);
+ if (column == 0) return;
+ int modelIndex = parent.columnCount == 0 ? Table.FIRST_COLUMN : parent.columns [index].modelIndex;
+ int fontHandle = font != null ? font.handle : 0;
+ OS.gtk_list_store_set (parent.modelHandle, handle, modelIndex + 4, fontHandle, -1);
+
+ if (font != null) {
+ boolean customDraw = (parent.columnCount == 0) ? parent.firstCustomDraw : parent.columns [index].customDraw;
+ if (!customDraw) {
+ int list = OS.gtk_tree_view_column_get_cell_renderers (column);
+ int length = OS.g_list_length (list);
+ int imageRenderer = OS.g_list_nth_data (list, length - 2);
+ int textRenderer = OS.g_list_nth_data (list, length - 1);
+ OS.g_list_free (list);
+ OS.gtk_tree_view_column_set_cell_data_func (column, imageRenderer, display.pixbufCellDataProc, parent.handle, 0);
+ OS.gtk_tree_view_column_set_cell_data_func (column, textRenderer, display.textCellDataProc, parent.handle, 0);
+ if (parent.columnCount == 0) {
+ parent.firstCustomDraw = true;
+ } else {
+ parent.columns [index].customDraw = true;
+ }
+ }
+ }
}
/**
@@ -694,9 +730,11 @@ public void setForeground (int index, Color color){
if (!customDraw) {
int list = OS.gtk_tree_view_column_get_cell_renderers (column);
int length = OS.g_list_length (list);
- int renderer = OS.g_list_nth_data (list, length - 1);
+ int textRenderer = OS.g_list_nth_data (list, length - 1);
+ int imageRenderer = OS.g_list_nth_data (list, length - 2);
OS.g_list_free (list);
- OS.gtk_tree_view_column_set_cell_data_func (column, renderer, display.cellDataProc, parent.handle, 0);
+ OS.gtk_tree_view_column_set_cell_data_func (column, textRenderer, display.textCellDataProc, parent.handle, 0);
+ OS.gtk_tree_view_column_set_cell_data_func (column, imageRenderer, display.pixbufCellDataProc, parent.handle, 0);
if (parent.columnCount == 0) {
parent.firstCustomDraw = true;
} else {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java
index 34043e2acd..79448b5d26 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java
@@ -202,7 +202,10 @@ public void addDisposeListener (DisposeListener listener) {
addListener (SWT.Dispose, typedListener);
}
-int cellDataProc (int tree_column, int cell, int tree_model, int iter, int data) {
+int textCellDataProc (int tree_column, int cell, int tree_model, int iter, int data) {
+ return 0;
+}
+int pixbufCellDataProc (int tree_column, int cell, int tree_model, int iter, int data) {
return 0;
}