[libgda] GdaBrowser: more work on the query exec. perspective
- From: Vivien Malerba <vivien src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [libgda] GdaBrowser: more work on the query exec. perspective
- Date: Fri, 4 Sep 2009 20:10:55 +0000 (UTC)
commit afb591798adb89ccd5473ce81b74a77103cfad66
Author: Vivien Malerba <malerba gnome-db org>
Date: Fri Sep 4 21:50:31 2009 +0200
GdaBrowser: more work on the query exec. perspective
po/POTFILES.in | 1 +
tools/browser/doc/gda-browser-sections.txt | 84 ++-
tools/browser/doc/tmpl/browser-connection.sgml | 9 +
tools/browser/query-exec/Makefile.am | 4 +
tools/browser/query-exec/gda-sql.lang | 632 +++++++++++++++
tools/browser/query-exec/query-console.c | 256 ++++++-
tools/browser/query-exec/query-editor.c | 1005 ++++++++++++++++++++++--
tools/browser/query-exec/query-editor.h | 67 ++-
8 files changed, 1961 insertions(+), 97 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index a36b405..dd1244d 100755
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -211,6 +211,7 @@ tools/browser/canvas/browser-canvas-print.c
tools/browser/canvas/browser-canvas-table.c
tools/browser/canvas/browser-canvas.c
tools/browser/common/objects-cloud.c
+tools/browser/query-exec/gda-sql.lang
tools/browser/schema-browser/favorite-selector.c
tools/browser/schema-browser/mgr-columns.c
tools/browser/schema-browser/objects-index.c
diff --git a/tools/browser/doc/gda-browser-sections.txt b/tools/browser/doc/gda-browser-sections.txt
index 1974a8b..f9272fd 100644
--- a/tools/browser/doc/gda-browser-sections.txt
+++ b/tools/browser/doc/gda-browser-sections.txt
@@ -13,8 +13,6 @@ browser_core_take_connection
browser_core_get_connections
browser_core_close_connection
browser_core_quit
-BrowserPerspectiveFactory
-BROWSER_PERSPECTIVE_FACTORY
browser_core_get_default_factory
browser_core_set_default_factory
browser_core_get_factories
@@ -70,10 +68,11 @@ AUTH_DIALOG_CLASS
<FILE>browser-favorites</FILE>
BrowserFavoritesPrivate
BrowserFavoritesType
+BROWSER_FAVORITES_NB_TYPES
+BrowserFavoritesAttributes
<TITLE>BrowserFavorites</TITLE>
BrowserFavorites
-BrowserFavoritesAttributes
-ORDER_KEY_SCHEMA
+browser_favorites_new
browser_favorites_add
browser_favorites_list
browser_favorites_delete
@@ -198,6 +197,47 @@ CC_IS_GRAY_BAR_CLASS
</SECTION>
<SECTION>
+<FILE>query-editor</FILE>
+QueryEditorPrivate
+<TITLE>QueryEditor</TITLE>
+QueryEditor
+QueryEditorHistoryItem
+query_editor_history_item_new
+query_editor_history_item_ref
+query_editor_history_item_unref
+QueryEditorHistoryBatch
+query_editor_history_batch_new
+query_editor_history_batch_ref
+query_editor_history_batch_unref
+query_editor_history_batch_add_item
+query_editor_history_batch_del_item
+QueryEditorMode
+query_editor_new
+query_editor_set_mode
+query_editor_get_mode
+query_editor_get_all_text
+query_editor_load_from_file
+query_editor_save_to_file
+query_editor_copy_clipboard
+query_editor_cut_clipboard
+query_editor_paste_clipboard
+query_editor_set_text
+query_editor_start_history_batch
+query_editor_add_history_item
+query_editor_get_current_history_item
+query_editor_get_current_history_batch
+query_editor_del_current_history_item
+query_editor_del_history_batch
+<SUBSECTION Standard>
+QUERY_EDITOR
+QUERY_IS_EDITOR
+QUERY_TYPE_EDITOR
+query_editor_get_type
+QUERY_EDITOR_CLASS
+QUERY_IS_EDITOR_CLASS
+</SECTION>
+
+<SECTION>
<FILE>browser-perspective</FILE>
BROWSER_PERSPECTIVE_TYPE
BROWSER_PERSPECTIVE
@@ -221,6 +261,9 @@ BrowserPerspectiveIface
BrowserPerspective
BrowserPageIface
BrowserPage
+BrowserPerspectiveFactory
+BROWSER_PERSPECTIVE_FACTORY
+ORDER_KEY_SCHEMA
</SECTION>
<SECTION>
@@ -265,6 +308,7 @@ BROWSER_STOCK_BOOKMARKS
STOCK_NEW_WINDOW
STOCK_ADD_BOOKMARK
STOCK_PRINT_SETUP
+STOCK_CONSOLE
browser_stock_icons_init
</SECTION>
@@ -281,6 +325,38 @@ browser_get_pixbuf_icon
</SECTION>
<SECTION>
+<FILE>query-exec-perspective</FILE>
+TYPE_QUERY_EXEC_PERSPECTIVE
+QUERY_EXEC_PERSPECTIVE
+QUERY_EXEC_PERSPECTIVE_CLASS
+IS_QUERY_EXEC_PERSPECTIVE
+QueryExecPerspectivePrivate
+<TITLE>QueryExecPerspective</TITLE>
+QueryExecPerspective
+query_exec_perspective_get_type
+query_exec_perspective_new
+</SECTION>
+
+<SECTION>
+<FILE>query-console</FILE>
+QUERY_CONSOLE_TYPE
+QUERY_CONSOLE
+QUERY_CONSOLE_CLASS
+IS_QUERY_CONSOLE
+IS_QUERY_CONSOLE_CLASS
+QueryConsolePrivate
+<TITLE>QueryConsole</TITLE>
+QueryConsole
+query_console_get_type
+query_console_new
+</SECTION>
+
+<SECTION>
+<FILE>perspective-main</FILE>
+query_exec_perspective_get_factory
+</SECTION>
+
+<SECTION>
<FILE>objects-cloud</FILE>
OBJECTS_CLOUD_TYPE
OBJECTS_CLOUD
diff --git a/tools/browser/doc/tmpl/browser-connection.sgml b/tools/browser/doc/tmpl/browser-connection.sgml
index 92e7c21..534ff21 100644
--- a/tools/browser/doc/tmpl/browser-connection.sgml
+++ b/tools/browser/doc/tmpl/browser-connection.sgml
@@ -135,3 +135,12 @@ An opened connection
@Returns:
+<!-- ##### FUNCTION browser_connection_create_parser ##### -->
+<para>
+
+</para>
+
+ bcnc:
+ Returns:
+
+
diff --git a/tools/browser/query-exec/Makefile.am b/tools/browser/query-exec/Makefile.am
index 79345f9..abfc15c 100644
--- a/tools/browser/query-exec/Makefile.am
+++ b/tools/browser/query-exec/Makefile.am
@@ -18,3 +18,7 @@ libperspective_la_SOURCES = \
perspective-main.h \
query-exec-perspective.h \
query-exec-perspective.c
+
+langspecdir=$(datadir)/libgda-$(GDA_ABI_MAJOR_VERSION).$(GDA_ABI_MINOR_VERSION)/language-specs
+langspec_DATA= \
+ gda-sql.lang
\ No newline at end of file
diff --git a/tools/browser/query-exec/gda-sql.lang b/tools/browser/query-exec/gda-sql.lang
new file mode 100644
index 0000000..d8d1e9c
--- /dev/null
+++ b/tools/browser/query-exec/gda-sql.lang
@@ -0,0 +1,632 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Author: Evert Verhellen <evert verhellen advalvas be>
+ Copyright (C) 2003, 2005 Evert Verhellen <evert verhellen advalvas be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+-->
+<language id="gda-sql" _name="GDA-SQL" version="2.0" _section="Sources">
+ <metadata>
+ <property name="mimetypes">text/x-sql</property>
+ <property name="globs">*.sql</property>
+ <property name="line-comment-start">--</property>
+ </metadata>
+
+ <styles>
+ <style id="comment" _name="Comment" map-to="def:comment"/>
+ <style id="floating-point" _name="Floating Point" map-to="def:floating-point"/>
+ <style id="string" _name="String" map-to="def:string"/>
+ <style id="keyword" _name="Keyword" map-to="def:keyword"/>
+ <style id="function" _name="Function" map-to="def:function"/>
+ <style id="decimal" _name="Decimal" map-to="def:decimal"/>
+ <style id="type" _name="Data Type" map-to="def:type"/>
+ <style id="variable" _name="Variable" map-to="def:type"/>
+ <style id="some-thing" _name="No idea what it is" map-to="def:preprocessor"/>
+ </styles>
+
+ <default-regex-options case-sensitive="false"/>
+
+ <definitions>
+
+ <context id="oracle-built-in-datatypes" style-ref="type">
+ <keyword>N?VARCHAR2</keyword>
+ <keyword>NUMBER</keyword>
+ <keyword>LONG</keyword>
+ <keyword>DATE</keyword>
+ <keyword>TIMESTAMP</keyword>
+ <keyword>INTERVAL</keyword>
+ <!-- FIXME no \n in patterns! -->
+ <keyword>(LONG[ \t\n]+)?RAW</keyword>
+ <keyword>U?ROWID</keyword>
+ <keyword>N?CHAR</keyword>
+ <keyword>(N?C|B)LOB</keyword>
+ <keyword>BFILE</keyword>
+ <keyword>BINARY_(FLOAT|DOUBLE)</keyword>
+ </context>
+
+ <context id="ansi-datatypes" style-ref="type">
+ <!-- FIXME no \n in patterns! -->
+ <keyword>(NATIONAL[ \t\n]+)?CHAR(ACTER)?([ \t\n]+VARYING)?</keyword>
+ <!-- FIXME no \n in patterns! -->
+ <keyword>NCHAR([ \t\n]+VARYING)?</keyword>
+ <keyword>NUMERIC|DECIMAL</keyword>
+ <keyword>INTEGER|INT|SMALLINT</keyword>
+ <!-- FIXME no \n in patterns! -->
+ <keyword>FLOAT|DOUBLE[ \t\n]+PRECISION|REAL</keyword>
+ </context>
+
+ <context id="sql-ds-and-db2-datatypes" style-ref="type">
+ <keyword>CHARACTER</keyword>
+ <!-- FIXME no \n in patterns! -->
+ <keyword>(LONG[ \t\n]+)?VARCHAR</keyword>
+ <keyword>DECIMAL</keyword>
+ <keyword>INTEGER|SMALLINT</keyword>
+ <keyword>FLOAT</keyword>
+ </context>
+
+ <context id="oracle-supplied-types" style-ref="type">
+ <keyword>SYS\.ANY(TYPE|DATA(SET)?)</keyword>
+ <keyword>XMLType</keyword>
+ <keyword>(HTTP|XDB|DB)?URIType</keyword>
+ <keyword>(MDSYS\.)?SDO_((TOPO_)?GEOMETRY|GEORASTER)</keyword>
+ <keyword>ORDSYS\.ORD(Audio|Doc|Image(Signature)?|Video)</keyword>
+ <keyword>SI_(StillImage|(Average|Positional)?Color|ColorHistogram|Texture|FeatureList)</keyword>
+ </context>
+
+ <context id="text-literals" style-ref="string">
+ <start>[NnQqUu]?(['`])</start>
+ <end>\%{1 start}</end>
+ <include>
+ <context ref="def:escape"/>
+ <context ref="def:line-continue"/>
+ </include>
+ </context>
+
+ <context id="integer-literals" style-ref="decimal">
+ <match>\b[0-9]+\b</match>
+ </context>
+
+ <context id="shortvariable" style-ref="variable">
+ <match>##[0-9a-zA-Z\+\- ]+(::[0-9a-zA-Z]+(::NULL)?)?</match>
+ </context>
+
+ <context id="longvariable" style-ref="variable">
+ <start>##( *)/\*</start>
+ <end>\*/</end>
+ <include>
+ <context ref="def:in-line-comment"/>
+ </include>
+ </context>
+
+ <context id="number-literals" style-ref="floating-point">
+ <match>(\b[0-9]+(\.[0-9]+)?|\.[0-9]+)([Ee][\+-]?[0-9]+)?\b</match>
+ </context>
+
+ <context id="size-clause" style-ref="decimal">
+ <match>\b[0-9]+[ \t]*([Kk]|[Mm]|[Gg]|[Tt])\b</match>
+ </context>
+
+ <context id="unlimited" style-ref="decimal">
+ <keyword>UNLIMITED</keyword>
+ </context>
+
+ <context id="null" style-ref="decimal">
+ <keyword>NULL</keyword>
+ </context>
+
+ <context id="block-comment" style-ref="comment">
+ <start>/\*</start>
+ <end>\*/</end>
+ <include>
+ <context ref="def:in-line-comment"/>
+ </include>
+ </context>
+
+ <context id="line-comment" style-ref="comment" end-at-line-end="true">
+ <start>--</start>
+ <include>
+ <context ref="def:in-line-comment"/>
+ </include>
+ </context>
+
+ <context id="numeric-functions" style-ref="function">
+ <keyword>ABS</keyword>
+ <keyword>A(COS|SIN|TAN2?)</keyword>
+ <keyword>BITAND</keyword>
+ <keyword>CEIL</keyword>
+ <keyword>(COS|SIN|TAN)H?</keyword>
+ <keyword>EXP</keyword>
+ <keyword>FLOOR</keyword>
+ <keyword>LN</keyword>
+ <keyword>LOG</keyword>
+ <keyword>MOD</keyword>
+ <keyword>NANVL</keyword>
+ <keyword>POWER</keyword>
+ <keyword>REMAINDER</keyword>
+ <keyword>ROUND</keyword>
+ <keyword>SIGN</keyword>
+ <keyword>SQRT</keyword>
+ <keyword>TRUNC</keyword>
+ <keyword>WIDTH_BUCKET</keyword>
+ </context>
+
+ <context id="character-functions-returning-character-values" style-ref="function">
+ <keyword>N?CHR</keyword>
+ <keyword>CONCAT</keyword>
+ <keyword>(NLS_)?(INITCAP|LOWER|UPPER)</keyword>
+ <keyword>(L|R)PAD</keyword>
+ <keyword>(L|R)?TRIM</keyword>
+ <keyword>NLSSORT</keyword>
+ <keyword>REGEXP_(REPLACE|SUBSTR)</keyword>
+ <keyword>REPLACE</keyword>
+ <keyword>SOUNDEX</keyword>
+ <keyword>SUBSTR</keyword>
+ <keyword>TRANSLATE</keyword>
+ <keyword>TREAT</keyword>
+ </context>
+
+ <context id="nls-character-functions" style-ref="function">
+ <keyword>NLS_CHARSET_DECL_LEN</keyword>
+ <keyword>NLS_CHARSET_(ID|NAME)</keyword>
+ </context>
+
+ <context id="character-functions-returning-number-values" style-ref="function">
+ <keyword>ASCII</keyword>
+ <keyword>INSTR</keyword>
+ <keyword>LENGTH</keyword>
+ <keyword>REGEXP_INSTR</keyword>
+ </context>
+
+ <context id="datetime-functions" style-ref="function">
+ <keyword>ADD_MONTHS</keyword>
+ <keyword>CURRENT_(DATE|TIMESTAMP)</keyword>
+ <keyword>DBTIMEZONE</keyword>
+ <keyword>EXTRACT</keyword>
+ <keyword>FROM_TZ</keyword>
+ <keyword>(LAST|NEXT)_DAY</keyword>
+ <keyword>LOCALTIMESTAMP</keyword>
+ <keyword>MONTHS_BETWEEN</keyword>
+ <keyword>NEW_TIME</keyword>
+ <keyword>NUMTO(DS|YM)INTERVAL</keyword>
+ <keyword>ROUND</keyword>
+ <keyword>SESSIONTIMEZONE</keyword>
+ <keyword>SYS_EXTRACT_UTC</keyword>
+ <keyword>SYS(DATE|TIMESTAMP)</keyword>
+ <keyword>TO_CHAR</keyword>
+ <keyword>TO_(DS|YM)INTERVAL</keyword>
+ <keyword>TO_TIMESTAMP(_TZ)?</keyword>
+ <keyword>TRUNC</keyword>
+ <keyword>TZ_OFFSET</keyword>
+ </context>
+
+ <context id="general-comparison-functions" style-ref="function">
+ <keyword>GREATEST</keyword>
+ <keyword>LEAST</keyword>
+ </context>
+
+ <context id="conversion-functions" style-ref="function">
+ <keyword>ASCIISTR</keyword>
+ <keyword>BIN_TO_NUM</keyword>
+ <keyword>CAST</keyword>
+ <keyword>CHARTOROWID</keyword>
+ <keyword>(DE)?COMPOSE</keyword>
+ <keyword>CONVERT</keyword>
+ <keyword>HEXTORAW</keyword>
+ <keyword>NUMTO(DS|YM)INTERVAL</keyword>
+ <keyword>RAWTON?HEX</keyword>
+ <keyword>ROWIDTON?CHAR</keyword>
+ <keyword>SCN_TO_TIMESTAMP</keyword>
+ <keyword>TIMESTAMP_TO_SCN</keyword>
+ <keyword>TO_BINARY_(DOUBLE|FLOAT)</keyword>
+ <keyword>TO_N?(CHAR|CLOB)</keyword>
+ <keyword>TO_DATE</keyword>
+ <keyword>TO_(DS|YM)INTERVAL</keyword>
+ <keyword>TO_LOB</keyword>
+ <keyword>TO_(MULTI|SINGLE)_BYTE</keyword>
+ <keyword>TO_NUMBER</keyword>
+ <keyword>TRANSLATE</keyword>
+ <keyword>UNISTR</keyword>
+ </context>
+
+ <context id="large-object-functions" style-ref="function">
+ <keyword>BFILENAME</keyword>
+ <keyword>EMPTY_(B|C)LOB</keyword>
+ </context>
+
+ <context id="collection-functions" style-ref="function">
+ <keyword>CARDINALITY</keyword>
+ <keyword>COLLECT</keyword>
+ <keyword>POWERMULTISET(_BY_CARDINALITY)?</keyword>
+ </context>
+
+ <context id="hierarchical-function" style-ref="function">
+ <keyword>SYS_CONNECT_BY_PATH</keyword>
+ </context>
+
+ <context id="data-mining-functions" style-ref="function">
+ <keyword>CLUSTER_(ID|PROBABILITY|SET)</keyword>
+ <keyword>FEATURE_(ID|SET|VALUE)</keyword>
+ <keyword>PREDICTION</keyword>
+ <keyword>PREDICTION_(COST|DETAILS|PROBABILITY|SET)</keyword>
+ </context>
+
+ <context id="xml-functions" style-ref="function">
+ <keyword>(APPEND|INSERT)CHILDXML</keyword>
+ <keyword>(DELETE|UPDATE)XML</keyword>
+ <keyword>DEPTH</keyword>
+ <keyword>EXISTSNODE</keyword>
+ <keyword>EXTRACT(VALUE)?</keyword>
+ <keyword>INSERTXMLBEFORE</keyword>
+ <keyword>PATH</keyword>
+ <keyword>SYS_DBURIGEN</keyword>
+ <keyword>SYS_XML(AGG|GEN)</keyword>
+ <keyword>XML(AGG|CDATA|COLATTVAL|COMMENT|CONCAT|ELEMENT|FOREST|PARSE|PI|QUERY|ROOT|SEQUENCE|SERIALIZE|TABLE|TRANSFORM)</keyword>
+ </context>
+
+ <context id="encoding-and-decoding-functions" style-ref="function">
+ <keyword>DECODE</keyword>
+ <keyword>DUMP</keyword>
+ <keyword>ORA_HASH</keyword>
+ <keyword>VSIZE</keyword>
+ </context>
+
+ <context id="null-related-functions" style-ref="function">
+ <keyword>COALESCE</keyword>
+ <keyword>LNNVL</keyword>
+ <keyword>NULLIF</keyword>
+ <keyword>NVL2?</keyword>
+ </context>
+
+ <context id="environment-and-identifier-functions" style-ref="function">
+ <keyword>SYS_CONTEXT</keyword>
+ <keyword>SYS_GUID</keyword>
+ <keyword>SYS_TYPEID</keyword>
+ <keyword>UID</keyword>
+ <keyword>USER</keyword>
+ <keyword>USERENV</keyword>
+ </context>
+
+ <context id="aggregate-functions" style-ref="function">
+ <keyword>AVG</keyword>
+ <keyword>CORR(_(S|K))?</keyword>
+ <keyword>COUNT</keyword>
+ <keyword>COVAR_(POP|SAMP)</keyword>
+ <keyword>CUME_DIST</keyword>
+ <keyword>(DENSE|PERCENT)_RANK</keyword>
+ <keyword>FIRST|LAST</keyword>
+ <keyword>GROUP_ID</keyword>
+ <keyword>GROUPING(_ID)?</keyword>
+ <keyword>MAX|MIN</keyword>
+ <keyword>MEDIAN</keyword>
+ <keyword>PERCENTILE_(CONT|DISC)</keyword>
+ <keyword>RANK</keyword>
+ <keyword>REGR_(SLOPE|INTERCEPT|COUNT|R2|AVGX|AVGY|SXX|SYY|SXY)</keyword>
+ <keyword>STATS_((BINOMIAL|F|KS|MW|WSR)_TEST|CROSSTAB|MODE|ONE_WAY_ANOVA|T_TEST_(ONE|PAIRED|INDEPU?))</keyword>
+ <keyword>STDDEV|VARIANCE</keyword>
+ <keyword>(STDDEV|VAR)_(POP|SAMP)</keyword>
+ <keyword>SUM</keyword>
+ </context>
+
+ <context id="analytic-functions" style-ref="function">
+ <keyword>AVG</keyword>
+ <keyword>CORR</keyword>
+ <keyword>COVAR_(POP|SAMP)</keyword>
+ <keyword>COUNT</keyword>
+ <keyword>CUME_DIST</keyword>
+ <keyword>(DENSE|PERCENT)_RANK</keyword>
+ <keyword>(FIRST|LAST)(_VALUE)?</keyword>
+ <keyword>LAG</keyword>
+ <keyword>LEAD</keyword>
+ <keyword>MAX|MIN</keyword>
+ <keyword>NTILE</keyword>
+ <keyword>PERCENTILE_(CONT|DISC)</keyword>
+ <keyword>RANK</keyword>
+ <keyword>RATIO_TO_REPORT</keyword>
+ <keyword>REGR_(SLOPE|INTERCEPT|COUNT|R2|AVGX|AVGY|SXX|SYY|SXY)</keyword>
+ <keyword>ROW_NUMBER</keyword>
+ <keyword>STDDEV|VARIANCE</keyword>
+ <keyword>(STDDEV|VAR)_(POP|SAMP)</keyword>
+ <keyword>SUM</keyword>
+ </context>
+
+ <context id="object-reference-functions" style-ref="function">
+ <keyword>DEREF</keyword>
+ <keyword>MAKE_REF</keyword>
+ <keyword>REF</keyword>
+ <keyword>REFTOHEX</keyword>
+ <keyword>VALUE</keyword>
+ </context>
+
+ <context id="model-functions" style-ref="function">
+ <keyword>CV</keyword>
+ <keyword>ITERATION_NUMBER</keyword>
+ <keyword>PRESENT(NN)?V</keyword>
+ <keyword>PREVIOUS</keyword>
+ </context>
+
+ <context id="ansi-reserved-words" style-ref="keyword">
+ <keyword>ADD</keyword>
+ <keyword>ALL</keyword>
+ <keyword>ALTER</keyword>
+ <keyword>AND</keyword>
+ <keyword>ANY</keyword>
+ <keyword>AS</keyword>
+ <keyword>ASC</keyword>
+ <keyword>BETWEEN</keyword>
+ <keyword>BY</keyword>
+ <keyword>CASE</keyword>
+ <keyword>CHECK</keyword>
+ <keyword>CREATE</keyword>
+ <keyword>CROSS</keyword>
+ <keyword>CURRENT</keyword>
+ <keyword>DECIMAL</keyword>
+ <keyword>DEFAULT</keyword>
+ <keyword>DELETE</keyword>
+ <keyword>DISTINCT</keyword>
+ <keyword>DROP</keyword>
+ <keyword>ELSE</keyword>
+ <keyword>END</keyword>
+ <keyword>FLOAT</keyword>
+ <keyword>FOR</keyword>
+ <keyword>FROM</keyword>
+ <keyword>FULL</keyword>
+ <keyword>GRANT</keyword>
+ <keyword>GROUP</keyword>
+ <keyword>HAVING</keyword>
+ <keyword>IMMEDIATE</keyword>
+ <keyword>INNER</keyword>
+ <keyword>INSERT</keyword>
+ <keyword>INTEGER</keyword>
+ <keyword>INTERSECT</keyword>
+ <keyword>INTO</keyword>
+ <keyword>IN</keyword>
+ <keyword>IS</keyword>
+ <keyword>JOIN</keyword>
+ <keyword>LEFT</keyword>
+ <keyword>LEVEL</keyword>
+ <keyword>LIKE</keyword>
+ <keyword>NATURAL</keyword>
+ <keyword>NOT</keyword>
+ <keyword>OF</keyword>
+ <keyword>ON</keyword>
+ <keyword>OPTION</keyword>
+ <keyword>ORDER</keyword>
+ <keyword>OR</keyword>
+ <keyword>OUTER</keyword>
+ <keyword>PRIOR</keyword>
+ <keyword>PRIVILEGES</keyword>
+ <keyword>PUBLIC</keyword>
+ <keyword>REVOKE</keyword>
+ <keyword>RIGHT</keyword>
+ <keyword>ROWS</keyword>
+ <keyword>SELECT</keyword>
+ <keyword>SESSION</keyword>
+ <keyword>SET</keyword>
+ <keyword>SIZE</keyword>
+ <keyword>SMALLINT</keyword>
+ <keyword>TABLE</keyword>
+ <keyword>THEN</keyword>
+ <keyword>TO</keyword>
+ <keyword>UNION</keyword>
+ <keyword>UNIQUE</keyword>
+ <keyword>UPDATE</keyword>
+ <keyword>USING</keyword>
+ <keyword>VALUES</keyword>
+ <keyword>VIEW</keyword>
+ <keyword>WHEN</keyword>
+ <keyword>WITH</keyword>
+ </context>
+
+ <context id="oracle-reserved-words" style-ref="keyword">
+ <keyword>ACCESS</keyword>
+ <keyword>AUDIT</keyword>
+ <keyword>CLUSTER</keyword>
+ <keyword>COMMENT</keyword>
+ <keyword>COMPRESS</keyword>
+ <keyword>CONNECT[ \t]+BY</keyword>
+ <keyword>CUBE</keyword>
+ <keyword>EXCLUSIVE</keyword>
+ <keyword>EXISTS</keyword>
+ <keyword>FILE</keyword>
+ <keyword>GROUPING[ \t]+SETS</keyword>
+ <keyword>IDENTIFIED</keyword>
+ <keyword>INCREMENT</keyword>
+ <keyword>INDEX</keyword>
+ <keyword>INITIAL</keyword>
+ <keyword>LOCK</keyword>
+ <keyword>MAXEXTENTS</keyword>
+ <keyword>MINUS</keyword>
+ <keyword>MLSLABEL</keyword>
+ <keyword>MODE</keyword>
+ <keyword>MODIFY</keyword>
+ <keyword>NOAUDIT</keyword>
+ <keyword>NOCOMPRESS</keyword>
+ <keyword>NOCYCLE</keyword>
+ <keyword>NOWAIT</keyword>
+ <keyword>OFFLINE</keyword>
+ <keyword>ONLINE</keyword>
+ <keyword>PCTFREE</keyword>
+ <keyword>RENAME</keyword>
+ <keyword>RESOURCE</keyword>
+ <keyword>ROLLUP</keyword>
+ <keyword>ROW</keyword>
+ <keyword>ROWNUM</keyword>
+ <keyword>SHARE</keyword>
+ <keyword>SIBLINGS</keyword>
+ <keyword>START[ \t]+WITH</keyword>
+ <keyword>SUCCESSFUL</keyword>
+ <keyword>SYNONYM</keyword>
+ <keyword>TRIGGER</keyword>
+ <keyword>VALIDATE</keyword>
+ <keyword>WHERE</keyword>
+ </context>
+
+ <context id="sql-statements" style-ref="keyword">
+ <prefix>^[ \t]*</prefix>
+ <keyword>ALTER[ \t]+(CLUSTER|DATABASE|DIMENSION|DISKGROUP|FUNCTION|INDEX(TYPE)?|JAVA|MATERIALIZED[ \t]+VIEW([ \t]+LOG)?|OPERATOR|OUTLINE|PACKAGE|PROCEDURE|PROFILE|RESOURCE[ \t]+COST|ROLE|ROLLBACK[ \t]+SEGMENT|SEQUENCE|SESSION|SYSTEM|TABLE(SPACE)?|TRIGGER|TYPE|USER|VIEW)</keyword>
+ <keyword>ANALYZE</keyword>
+ <keyword>(DIS)?ASSOCIATE[ \t]+STATISTICS</keyword>
+ <keyword>CALL</keyword>
+ <keyword>COMMIT([ \t]+WORK)?</keyword>
+ <keyword>CREATE[ \t]+(CLUSTER|CONTEXT|CONTROLFILE|DATABASE([ \t]+LINK)?|DIMENSION|DIRECTORY|DISKGROUP|FUNCTION|INDEX(TYPE)?|JAVA|LIBRARY|MATERIALIZED[ \t]+VIEW([ \t]+LOG)?|OPERATOR|OUTLINE|PACKAGE([ \t]+BODY)?|S?PFILE|PROCEDURE|PROFILE|RESTORE[ \t]+POINT|ROLE|ROLLBACK[ \t]+SEGMENT|SCHEMA|SEQUENCE|SYNONYM|TABLE(SPACE)?|TRIGGER|TYPE([ \t]+BODY)?|USER|VIEW)</keyword>
+ <keyword>DROP[ \t]+(CLUSTER|CONTEXT|DATABASE([ \t]+LINK)?|DIMENSION|DIRECTORY|DISKGROUP|FUNCTION|INDEX(TYPE)?|JAVA|LIBRARY|MATERIALIZED[ \t]+VIEW([ \t]+LOG)?|OPERATOR|OUTLINE|PACKAGE|PROCEDURE|PROFILE|RESTORE[ \t]+POINT|ROLE|ROLLBACK[ \t]+SEGMENT|SEQUENCE|SYNONYM|TABLE(SPACE)?|TRIGGER|TYPE([ \t]+BODY)?|USER|VIEW)</keyword>
+ <keyword>EXPLAIN[ \t]+PLAN</keyword>
+ <keyword>FLASHBACK[ \t]+(DATABASE|TABLE)</keyword>
+ <keyword>LOCK[ \t]+TABLE</keyword>
+ <keyword>MERGE</keyword>
+ <keyword>PURGE</keyword>
+ <keyword>ROLLBACK</keyword>
+ <keyword>SAVEPOINT</keyword>
+ <keyword>SET[ \t]+CONSTRAINTS?</keyword>
+ <keyword>SET[ \t]+ROLE</keyword>
+ <keyword>SET[ \t]+TRANSACTION</keyword>
+ <keyword>TRUNCATE</keyword>
+ </context>
+
+ <context id="operators" style-ref="keyword">
+ <keyword>CONNECT_BY_ROOT</keyword>
+ <keyword>MULTISET[ \t]+(EXCEPT|INTERSECT|UNION)</keyword>
+ </context>
+
+ <context id="conditions" style-ref="keyword">
+ <keyword>SOME</keyword>
+ <keyword>IS[ \t]+(NOT[ \t]+)?(NAN|INFINITE)</keyword>
+ <keyword>IS[ \t]+(NOT[ \t]+)?NULL</keyword>
+ <keyword>(EQUALS|UNDER)_PATH</keyword>
+ <keyword>(NOT[ \t]+)?IN</keyword>
+ <keyword>IS[ \t]+(NOT[ \t]+)?A[ \t]+SET</keyword>
+ <keyword>IS[ \t]+(NOT[ \t]+)?EMPTY</keyword>
+ <keyword>IS[ \t]+(NOT[ \t]+)?OF([ \t]+TYPE)?</keyword>
+ <keyword>IS[ \t]+PRESENT</keyword>
+ <keyword>(NOT[ \t]+)?LIKE(C|2|4)?</keyword>
+ <keyword>(NOT[ \t]+)?MEMBER([ \t]+OF)?</keyword>
+ <keyword>REGEXP_LIKE</keyword>
+ <keyword>(NOT[ \t]+)?SUBMULTISET([ \t]+OF)?</keyword>
+ </context>
+
+ <context id="sql-plus-at-sign" style-ref="some-thing">
+ <match>^[ \t]*@</match>
+ </context>
+
+ <context id="sql-plus-double-at-sign" style-ref="some-thing">
+ <match>^[ \t]*@@</match>
+ </context>
+
+ <context id="sql-plus-slash" style-ref="some-thing">
+ <match>^[ \t]*/</match>
+ </context>
+
+ <context id="sql-plus-commands" style-ref="some-thing">
+ <prefix>^[ \t]*</prefix>
+ <keyword>ACC(EPT)?</keyword>
+ <keyword>A(PPEND)?</keyword>
+ <keyword>ARCHIVE[ \t]LOG</keyword>
+ <keyword>ATTRIBUTE</keyword>
+ <keyword>BRE(AK)?</keyword>
+ <keyword>BTI(TLE)?</keyword>
+ <keyword>C(HANGE)?</keyword>
+ <keyword>CL(EAR)?</keyword>
+ <keyword>COL(UMN)?</keyword>
+ <keyword>COMP(UTE)?</keyword>
+ <keyword>CONN(ECT)?</keyword>
+ <keyword>COPY</keyword>
+ <keyword>DEF(INE)?</keyword>
+ <keyword>DEL</keyword>
+ <keyword>DESC(RIBE)?</keyword>
+ <keyword>DISC(ONNECT)?</keyword>
+ <keyword>ED(IT)?</keyword>
+ <keyword>EXEC(UTE)?</keyword>
+ <keyword>EXIT|QUIT</keyword>
+ <keyword>GET</keyword>
+ <keyword>HELP</keyword>
+ <keyword>HO(ST)?</keyword>
+ <keyword>I(NPUT)?</keyword>
+ <keyword>L(IST)?</keyword>
+ <keyword>PASSW(ORD)?</keyword>
+ <keyword>PAU(SE)?</keyword>
+ <keyword>PRI(NT)?</keyword>
+ <keyword>PRO(MPT)?</keyword>
+ <keyword>RECOVER</keyword>
+ <keyword>REM(ARK)?</keyword>
+ <keyword>REPF(OOTER)?</keyword>
+ <keyword>REPH(EADER)?</keyword>
+ <keyword>R(UN)?</keyword>
+ <keyword>SAV(E)?</keyword>
+ <keyword>SET[ \t]+(APPI(NFO)?|ARRAY(SIZE)?|AUTO(COMMIT)?|AUTOP(RINT)?|AUTORECOVERY|AUTOT(RACE)?|BLO(CKTERMINATOR)?|CMDS(EP)?|COLSEP|COM(PATIBILITY)?|CON(CAT)?|COPYC(OMMIT)?|COPYTYPECHECK|DEF(INE)?|DESCRIBE|ECHO|EDITF(ILE)?|EMB(EDDED)?|ESC(APE)?|FEED(BACK)?|FLAGGER|FLU(SH)?|HEA(DING)?|HEADS(EP)?|INSTANCE|LIN(ESIZE)?|LOBOF(FSET)?|LOGSOURCE|LONG|LONGC(HUNKSIZE)?|MARK(UP)?|NEWP(AGE)?|NULL|NUMF(ORMAT)?|NUM(WIDTH)?|PAGES(IZE)?|PAU(SE)?|RECSEP|RECSEPCHAR|SERVEROUT(PUT)?|SHIFT(INOUT)?|SHOW(MODE)?|SQLBL(ANKLINES)?|SQLC(ASE)?|SQLCO(NTINUE)?|SQLN(UMBER)?|SQLPLUSCOMPAT(IBILITY)?|SQLPRE(FIX)?|SQLP(ROMPT)?|SQLT(ERMINATOR)?|SUF(FIX)?|TAB|TERM(OUT)?|TI(ME)?|TIMI(NG)?|TRIM(OUT)?|TRIMS(POOL)?|UND(ERLINE)?|VER(IFY)?|WRA(P)?)</keyword>
+ <keyword>SHO(W)?</keyword>
+ <keyword>SHUTDOWN</keyword>
+ <keyword>SPO(OL)?</keyword>
+ <keyword>STA(RT)?</keyword>
+ <keyword>STARTUP</keyword>
+ <keyword>STORE</keyword>
+ <keyword>TIMI(NG)?</keyword>
+ <keyword>TTI(TLE)?</keyword>
+ <keyword>UNDEF(INE)?</keyword>
+ <keyword>VAR(IABLE)?</keyword>
+ <keyword>WHENEVER[ \t]+(OS|SQL)ERROR</keyword>
+ </context>
+
+ <context id="gda-sql">
+ <include>
+ <context ref="oracle-built-in-datatypes"/>
+ <context ref="ansi-datatypes"/>
+ <context ref="sql-ds-and-db2-datatypes"/>
+ <context ref="oracle-supplied-types"/>
+ <context ref="text-literals"/>
+ <context ref="integer-literals"/>
+ <context ref="shortvariable"/>
+ <context ref="longvariable"/>
+ <context ref="number-literals"/>
+ <context ref="size-clause"/>
+ <context ref="unlimited"/>
+ <context ref="null"/>
+ <context ref="block-comment"/>
+ <context ref="line-comment"/>
+ <context ref="numeric-functions"/>
+ <context ref="character-functions-returning-character-values"/>
+ <context ref="nls-character-functions"/>
+ <context ref="character-functions-returning-number-values"/>
+ <context ref="datetime-functions"/>
+ <context ref="general-comparison-functions"/>
+ <context ref="conversion-functions"/>
+ <context ref="large-object-functions"/>
+ <context ref="collection-functions"/>
+ <context ref="hierarchical-function"/>
+ <context ref="data-mining-functions"/>
+ <context ref="xml-functions"/>
+ <context ref="encoding-and-decoding-functions"/>
+ <context ref="null-related-functions"/>
+ <context ref="environment-and-identifier-functions"/>
+ <context ref="aggregate-functions"/>
+ <context ref="analytic-functions"/>
+ <context ref="object-reference-functions"/>
+ <context ref="model-functions"/>
+ <context ref="ansi-reserved-words"/>
+ <context ref="oracle-reserved-words"/>
+ <context ref="sql-statements"/>
+ <context ref="operators"/>
+ <context ref="conditions"/>
+ <context ref="sql-plus-at-sign"/>
+ <context ref="sql-plus-double-at-sign"/>
+ <context ref="sql-plus-slash"/>
+ <context ref="sql-plus-commands"/>
+ </include>
+ </context>
+
+ </definitions>
+</language>
diff --git a/tools/browser/query-exec/query-console.c b/tools/browser/query-exec/query-console.c
index 9b5944c..3f7f429 100644
--- a/tools/browser/query-exec/query-console.c
+++ b/tools/browser/query-exec/query-console.c
@@ -40,11 +40,17 @@ struct _QueryConsolePrivate {
CcGrayBar *header;
GtkWidget *vpaned; /* top=>query editor, bottom=>results */
QueryEditor *editor;
+
+ GtkToggleButton *params_toggle;
+ GtkWidget *params_form;
+
+ QueryEditor *history;
};
static void query_console_class_init (QueryConsoleClass *klass);
static void query_console_init (QueryConsole *tconsole, QueryConsoleClass *klass);
static void query_console_dispose (GObject *object);
+static void query_console_show_all (GtkWidget *widget);
/* BrowserPage interface */
static void query_console_page_init (BrowserPageIface *iface);
@@ -71,6 +77,19 @@ query_console_class_init (QueryConsoleClass *klass)
parent_class = g_type_class_peek_parent (klass);
object_class->dispose = query_console_dispose;
+ GTK_WIDGET_CLASS (klass)->show_all = query_console_show_all;
+}
+
+static void
+query_console_show_all (GtkWidget *widget)
+{
+ QueryConsole *tconsole = (QueryConsole *) widget;
+ GTK_WIDGET_CLASS (parent_class)->show_all (widget);
+
+ if (gtk_toggle_button_get_active (tconsole->priv->params_toggle))
+ gtk_widget_show (tconsole->priv->params_form);
+ else
+ gtk_widget_hide (tconsole->priv->params_form);
}
static void
@@ -137,6 +156,14 @@ query_console_get_type (void)
return type;
}
+static GtkWidget *make_small_button (gboolean is_toggle,
+ const gchar *label, const gchar *stock_id, const gchar *tooltip);
+
+static void sql_clear_clicked_cb (GtkButton *button, QueryConsole *tconsole);
+static void sql_variables_clicked_cb (GtkToggleButton *button, QueryConsole *tconsole);
+static void sql_execute_clicked_cb (GtkButton *button, QueryConsole *tconsole);
+static void sql_indent_clicked_cb (GtkButton *button, QueryConsole *tconsole);
+
/**
* query_console_new
*
@@ -169,22 +196,200 @@ query_console_new (BrowserConnection *bcnc)
tconsole->priv->vpaned = NULL;
gtk_box_pack_start (GTK_BOX (tconsole), vpaned, TRUE, TRUE, 0);
- GtkWidget *wid;
+ /* top paned for the editor */
+ GtkWidget *wid, *vbox, *hbox, *bbox, *hpaned, *button;
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_paned_add1 (GTK_PANED (vpaned), vbox);
+
+ wid = gtk_label_new ("");
+ str = g_strdup_printf ("<b>%s</b>", _("SQL code to execute:"));
+ gtk_label_set_markup (GTK_LABEL (wid), str);
+ g_free (str);
+ gtk_misc_set_alignment (GTK_MISC (wid), 0., -1);
+ gtk_box_pack_start (GTK_BOX (vbox), wid, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+
+ hpaned = gtk_hpaned_new ();
+ gtk_box_pack_start (GTK_BOX (hbox), hpaned, TRUE, TRUE, 0);
+
wid = query_editor_new ();
tconsole->priv->editor = QUERY_EDITOR (wid);
- gtk_paned_add1 (GTK_PANED (vpaned), wid);
+ gtk_paned_pack1 (GTK_PANED (hpaned), wid, TRUE, FALSE);
+
+ wid = gtk_label_new ("Here goes the\nparams' form");
+ tconsole->priv->params_form = wid;
+ gtk_paned_pack2 (GTK_PANED (hpaned), wid, FALSE, TRUE);
+
+ bbox = gtk_vbutton_box_new ();
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
+ gtk_box_pack_start (GTK_BOX (hbox), bbox, FALSE, FALSE, 5);
+
+ button = make_small_button (FALSE, _("Clear"), GTK_STOCK_CLEAR, _("Clear the editor"));
+ gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (sql_clear_clicked_cb), tconsole);
+
+ button = make_small_button (TRUE, _("Variables"), NULL, _("Show variables needed\nto execute SQL"));
+ gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+ tconsole->priv->params_toggle = GTK_TOGGLE_BUTTON (button);
+ g_signal_connect (button, "toggled",
+ G_CALLBACK (sql_variables_clicked_cb), tconsole);
+
+ button = make_small_button (FALSE, _("Execute"), GTK_STOCK_EXECUTE, _("Execute SQL in editor"));
+ gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (sql_execute_clicked_cb), tconsole);
+
+ button = make_small_button (FALSE, _("Indent"), GTK_STOCK_INDENT, _("Indent SQL in editor"));
+ gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (sql_indent_clicked_cb), tconsole);
+
+ /* bottom paned for the results and history */
+ hpaned = gtk_hpaned_new ();
+ gtk_paned_add2 (GTK_PANED (vpaned), hpaned);
+
+ /* bottom left */
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_paned_pack1 (GTK_PANED (hpaned), vbox, FALSE, TRUE);
+
+ wid = gtk_label_new ("");
+ str = g_strdup_printf ("<b>%s</b>", _("Execution history:"));
+ gtk_label_set_markup (GTK_LABEL (wid), str);
+ g_free (str);
+ gtk_misc_set_alignment (GTK_MISC (wid), 0., -1);
+ gtk_box_pack_start (GTK_BOX (vbox), wid, FALSE, FALSE, 0);
+
+ wid = query_editor_new ();
+ tconsole->priv->history = QUERY_EDITOR (wid);
+ query_editor_set_mode (tconsole->priv->history, QUERY_EDITOR_HISTORY);
+ gtk_widget_set_size_request (wid, 200, -1);
+ gtk_box_pack_start (GTK_BOX (vbox), wid, TRUE, TRUE, 0);
+
+ bbox = gtk_vbutton_box_new ();
+ gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
+
+ button = make_small_button (FALSE, _("Delete"), GTK_STOCK_DELETE, _("Delete history item"));
+ gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+
+ /* bottom right */
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_paned_pack2 (GTK_PANED (hpaned), vbox, TRUE, FALSE);
+
+ wid = gtk_label_new ("");
+ str = g_strdup_printf ("<b>%s</b>", _("Execution Results:"));
+ gtk_label_set_markup (GTK_LABEL (wid), str);
+ g_free (str);
+ gtk_misc_set_alignment (GTK_MISC (wid), 0., -1);
+ gtk_box_pack_start (GTK_BOX (vbox), wid, FALSE, FALSE, 0);
+
+ wid = gtk_label_new ("Here go the\nresults' form");
+ gtk_box_pack_start (GTK_BOX (vbox), wid, TRUE, TRUE, 0);
/* show everything */
gtk_widget_show_all (vpaned);
+ gtk_widget_hide (tconsole->priv->params_form);
return (GtkWidget*) tconsole;
}
-/*
- * UI actions
- */
+static GtkWidget *
+make_small_button (gboolean is_toggle, const gchar *label, const gchar *stock_id, const gchar *tooltip)
+{
+ GtkWidget *button, *hbox = NULL;
+
+ if (is_toggle)
+ button = gtk_toggle_button_new ();
+ else
+ button = gtk_button_new ();
+ if (label && stock_id) {
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (button), hbox);
+ gtk_widget_show (hbox);
+ }
+
+ if (stock_id) {
+ GtkWidget *image;
+ image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
+ if (hbox)
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+ else
+ gtk_container_add (GTK_CONTAINER (button), image);
+ gtk_widget_show (image);
+ }
+ if (label) {
+ GtkWidget *wid;
+ wid = gtk_label_new (label);
+ if (hbox)
+ gtk_box_pack_start (GTK_BOX (hbox), wid, FALSE, FALSE, 5);
+ else
+ gtk_container_add (GTK_CONTAINER (button), wid);
+ gtk_widget_show (wid);
+ }
+
+ if (tooltip)
+ gtk_widget_set_tooltip_text (button, tooltip);
+ return button;
+}
+
static void
-query_execute_cb (GtkAction *action, QueryConsole *tconsole)
+sql_variables_clicked_cb (GtkToggleButton *button, QueryConsole *tconsole)
+{
+ if (gtk_toggle_button_get_active (button))
+ gtk_widget_show (tconsole->priv->params_form);
+ else
+ gtk_widget_hide (tconsole->priv->params_form);
+}
+
+static void
+sql_clear_clicked_cb (GtkButton *button, QueryConsole *tconsole)
+{
+ query_editor_set_text (tconsole->priv->editor, NULL);
+}
+
+static void
+sql_indent_clicked_cb (GtkButton *button, QueryConsole *tconsole)
+{
+ gchar *sql;
+ GdaBatch *batch;
+
+ if (!tconsole->priv->parser)
+ tconsole->priv->parser = browser_connection_create_parser (tconsole->priv->bcnc);
+
+ sql = query_editor_get_all_text (tconsole->priv->editor);
+ batch = gda_sql_parser_parse_string_as_batch (tconsole->priv->parser, sql, NULL, NULL);
+ g_free (sql);
+ if (batch) {
+ GString *string;
+ const GSList *stmt_list, *list;
+ stmt_list = gda_batch_get_statements (batch);
+ string = g_string_new ("");
+ for (list = stmt_list; list; list = list->next) {
+ GError *error = NULL;
+ sql = gda_statement_to_sql_extended (GDA_STATEMENT (list->data), NULL, NULL,
+ GDA_STATEMENT_SQL_PRETTY |
+ GDA_STATEMENT_SQL_PARAMS_SHORT,
+ NULL, &error);
+ if (!sql)
+ sql = gda_statement_to_sql (GDA_STATEMENT (list->data), NULL, NULL);
+ if (list != stmt_list)
+ g_string_append (string, "\n\n");
+ g_string_append_printf (string, "%s;\n", sql);
+ g_free (sql);
+
+ }
+ g_object_unref (batch);
+
+ query_editor_set_text (tconsole->priv->editor, string->str);
+ g_string_free (string, TRUE);
+ }
+}
+
+static void
+sql_execute_clicked_cb (GtkButton *button, QueryConsole *tconsole)
{
gchar *sql;
const gchar *remain;
@@ -204,9 +409,44 @@ query_execute_cb (GtkAction *action, QueryConsole *tconsole)
g_free (sql);
return;
}
-
g_free (sql);
- TO_IMPLEMENT;
+
+ QueryEditorHistoryBatch *hbatch;
+ GTimeVal tv;
+ g_get_current_time (&tv);
+ hbatch = query_editor_history_batch_new (tv);
+ query_editor_start_history_batch (tconsole->priv->history, hbatch);
+ query_editor_history_batch_unref (hbatch);
+
+ const GSList *stmt_list, *list;
+ stmt_list = gda_batch_get_statements (batch);
+ for (list = stmt_list; list; list = list->next) {
+ QueryEditorHistoryItem *history;
+ GdaSqlStatement *sqlst;
+ g_object_get (G_OBJECT (list->data), "structure", &sqlst, NULL);
+ if (!sqlst->sql) {
+ sql = gda_statement_to_sql (GDA_STATEMENT (list->data), NULL, NULL);
+ history = query_editor_history_item_new (sql, NULL, NULL);
+ g_free (sql);
+ }
+ else
+ history = query_editor_history_item_new (sqlst->sql, NULL, NULL);
+ gda_sql_statement_free (sqlst);
+
+ query_editor_add_history_item (tconsole->priv->history, history);
+ query_editor_history_item_unref (history);
+ }
+ g_object_unref (batch);
+}
+
+
+/*
+ * UI actions
+ */
+static void
+query_execute_cb (GtkAction *action, QueryConsole *tconsole)
+{
+ sql_execute_clicked_cb (NULL, tconsole);
}
#ifdef HAVE_GTKSOURCEVIEW
diff --git a/tools/browser/query-exec/query-editor.c b/tools/browser/query-exec/query-editor.c
index 27349c9..765ac7b 100644
--- a/tools/browser/query-exec/query-editor.c
+++ b/tools/browser/query-exec/query-editor.c
@@ -1,5 +1,5 @@
/* GNOME DB library
- * Copyright (C) 1999 - 2008 The GNOME Foundation.
+ * Copyright (C) 1999 - 2009 The GNOME Foundation.
*
* AUTHORS:
* Rodrigo Moya <rodrigo gnome-db org>
@@ -21,33 +21,82 @@
* Boston, MA 02111-1307, USA.
*/
+#include <glib/gi18n-lib.h>
#include <string.h>
#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
#ifdef HAVE_GTKSOURCEVIEW
#include <gtksourceview/gtksourceview.h>
#include <gtksourceview/gtksourcelanguagemanager.h>
#include <gtksourceview/gtksourcebuffer.h>
+ #include <gtksourceview/gtksourcestyleschememanager.h>
+ #include <gtksourceview/gtksourcestylescheme.h>
#endif
#include "query-editor.h"
+#include <binreloc/gda-binreloc.h>
-#define PARENT_TYPE GTK_TYPE_VBOX
+#define QUERY_EDITOR_LANGUAGE_SQL "gda-sql"
typedef void (* CreateTagsFunc) (QueryEditor *editor, const gchar *language);
+typedef struct {
+ QueryEditorHistoryBatch *batch; /* ref held here */
+ QueryEditorHistoryItem *item; /* ref held here */
+ GtkTextTag *tag; /* ref held here */
+ GtkTextMark *start_mark; /* ref NOT held here */
+ GtkTextMark *end_mark; /* ref NOT held here */
+
+ gint ref_count;
+} HistItemData;
+static HistItemData *hist_item_data_new (void);
+static HistItemData *hist_item_data_ref (HistItemData *hdata);
+static void hist_item_data_unref (HistItemData *hdata);
+
struct _QueryEditorPrivate {
+ QueryEditorMode mode;
GtkWidget *scrolled_window;
GtkWidget *text;
- guint config_lid;
+
+ /* HISTORY mode */
+ guint ts_timeout_id;
+ GSList *batches_list; /* list of QueryEditorHistoryBatch, in reverse order, refs held here */
+ GHashTable *hash; /* crossed references:
+ * QueryEditorHistoryBatch --> HistItemData on @batch
+ * QueryEditorHistoryItem --> HistItemData on @item
+ * GtkTextTag --> HistItemData on @tag
+ *
+ * hash table holds references to all HistItemData
+ */
+ QueryEditorHistoryBatch *insert_into_batch; /* hold ref here */
+ HistItemData *hist_focus; /* ref held here */
};
static void query_editor_class_init (QueryEditorClass *klass);
static void query_editor_init (QueryEditor *editor, QueryEditorClass *klass);
static void query_editor_finalize (GObject *object);
+static void query_editor_map (GtkWidget *widget);
+
static GObjectClass *parent_class = NULL;
static GHashTable *supported_languages = NULL;
static gint number_of_objects = 0;
+static void focus_on_hist_data (QueryEditor *editor, HistItemData *hdata);
+static HistItemData *get_next_hist_data (QueryEditor *editor, HistItemData *hdata);
+static HistItemData *get_prev_hist_data (QueryEditor *editor, HistItemData *hdata);
+
+static gboolean timestamps_update_cb (QueryEditor *editor);
+
+/* signals */
+enum
+{
+ CHANGED,
+ LAST_SIGNAL
+};
+
+static gint query_editor_signals[LAST_SIGNAL] = { 0 };
+
+
/*
* Private functions
*/
@@ -58,6 +107,12 @@ create_tags_for_sql (QueryEditor *editor, const gchar *language)
#ifdef HAVE_GTKSOURCEVIEW
GtkSourceLanguageManager *mgr;
GtkSourceLanguage *lang;
+ gchar ** current_search_path;
+ gint len;
+ gchar ** search_path;
+
+ GtkSourceStyleSchemeManager* sch_mgr;
+ GtkSourceStyleScheme *sch;
#endif
g_return_if_fail (language != NULL);
@@ -66,14 +121,37 @@ create_tags_for_sql (QueryEditor *editor, const gchar *language)
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->priv->text));
#ifdef HAVE_GTKSOURCEVIEW
mgr = gtk_source_language_manager_new ();
- lang = gtk_source_language_manager_get_language (mgr, "sql");
- if (lang) {
- gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (buffer), lang);
- /* FIXME: extend for Gda's variables syntax */
+ /* alter search path */
+ current_search_path = (gchar **) gtk_source_language_manager_get_search_path (mgr);
+ len = g_strv_length (current_search_path);
+ search_path = g_new0 (gchar*, len + 2);
+ memcpy (search_path, current_search_path, sizeof (gchar*) * len);
+ search_path [len] = gda_gbr_get_file_path (GDA_DATA_DIR, LIBGDA_ABI_NAME, "language-specs", NULL);
+ gtk_source_language_manager_set_search_path (mgr, search_path);
+ g_free (search_path [len]);
+ g_free (search_path);
+
+ lang = gtk_source_language_manager_get_language (mgr, "gda-sql");
+
+ if (!lang) {
+ gchar *tmp;
+ tmp = gda_gbr_get_file_path (GDA_DATA_DIR, LIBGDA_ABI_NAME, "language-spec", NULL);
+ g_print ("Could not find the gda-sql.lang file in %s,\nusing the default SQL highlighting rules.\n",
+ tmp);
+ g_free (tmp);
+ lang = gtk_source_language_manager_get_language (mgr, "sql");
}
+ if (lang)
+ gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (buffer), lang);
g_object_unref (mgr);
+
+ sch_mgr = gtk_source_style_scheme_manager_get_default ();
+ sch = gtk_source_style_scheme_manager_get_scheme (sch_mgr, "tango");
+ if (sch)
+ gtk_source_buffer_set_style_scheme (GTK_SOURCE_BUFFER (buffer), sch);
+
#endif
}
@@ -88,38 +166,91 @@ query_editor_class_init (QueryEditorClass *klass)
parent_class = g_type_class_peek_parent (klass);
+ query_editor_signals[CHANGED] =
+ g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryEditorClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
object_class->finalize = query_editor_finalize;
+ GTK_WIDGET_CLASS (object_class)->map = query_editor_map;
}
-#ifdef HAVE_GCONF
static void
-configuration_changed_cb (GConfClient *conf_client, guint cnxn_id, GConfEntry *entry, gpointer user_data)
+text_buffer_changed_cb (GtkTextBuffer *buffer, QueryEditor *editor)
{
- QueryEditor *editor = (QueryEditor *) user_data;
-
- g_return_if_fail (QUERY_IS_EDITOR (editor));
+ if (editor->priv->mode != QUERY_EDITOR_HISTORY)
+ g_signal_emit (editor, query_editor_signals[CHANGED], 0);
+}
- if (!strcmp (entry->key, QUERY_CONFIG_KEY_EDITOR_SHOW_LINE_NUMBERS)) {
-#ifdef HAVE_GTKSOURCEVIEW
- gtk_source_view_set_show_line_numbers (
- GTK_SOURCE_VIEW (editor->priv->text),
- gconf_client_get_bool (gconf_client_get_default (), QUERY_CONFIG_KEY_EDITOR_SHOW_LINE_NUMBERS, NULL));
-#else
-#endif
- } else if (!strcmp (entry->key, QUERY_CONFIG_KEY_EDITOR_TAB_STOP)) {
-#ifdef HAVE_GTKSOURCEVIEW
- int tab = gconf_client_get_int (gconf_client_get_default (), QUERY_CONFIG_KEY_EDITOR_TAB_STOP, NULL);
- gtk_source_view_set_tab_width (GTK_SOURCE_VIEW (editor->priv->text),
- tab ? tab : 8);
-#else
-#endif
- } else if (!strcmp (entry->key, QUERY_CONFIG_KEY_EDITOR_HIGHLIGHT)) {
- query_editor_set_highlight_syntax (editor,
- gconf_client_get_bool (gconf_client_get_default (),
- QUERY_CONFIG_KEY_EDITOR_HIGHLIGHT, NULL));
+/*
+ * Returns: -1 if none focussed
+ */
+static gboolean
+event_after (GtkWidget *text_view, GdkEvent *ev, QueryEditor *editor)
+{
+ GtkTextIter start, end, iter;
+ GtkTextBuffer *buffer;
+ GdkEventButton *event;
+ gint x, y;
+
+ if (editor->priv->mode != QUERY_EDITOR_HISTORY)
+ return FALSE;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
+ if (ev->type == GDK_BUTTON_RELEASE) {
+ event = (GdkEventButton *)ev;
+
+ if (event->button != 1)
+ return FALSE;
+
+ /* we shouldn't follow a link if the user has selected something */
+ gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+ if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
+ return FALSE;
+
+ gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
+ GTK_TEXT_WINDOW_WIDGET,
+ event->x, event->y, &x, &y);
+
+ gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y);
+
+ /* go through tags */
+ GSList *tags = NULL, *tagp = NULL;
+ HistItemData *hist_focus = NULL;
+ tags = gtk_text_iter_get_tags (&iter);
+ for (tagp = tags; tagp; tagp = tagp->next) {
+ hist_focus = g_hash_table_lookup (editor->priv->hash, tagp->data);
+ if (hist_focus)
+ break;
+ }
+ focus_on_hist_data (editor, hist_focus);
+
+ if (tags)
+ g_slist_free (tags);
+ }
+ else if ((ev->type == GDK_KEY_PRESS) &&
+ (((((GdkEventKey*) ev)->keyval == GDK_Up)) || ((((GdkEventKey*) ev)->keyval == GDK_Down)))) {
+ HistItemData *nfocus = NULL;
+ if (editor->priv->hist_focus) {
+ if (((GdkEventKey*) ev)->keyval == GDK_Up)
+ nfocus = get_prev_hist_data (editor, editor->priv->hist_focus);
+ else
+ nfocus = get_next_hist_data (editor, editor->priv->hist_focus);
+ if (!nfocus)
+ nfocus = editor->priv->hist_focus;
+ }
+
+ focus_on_hist_data (editor, nfocus);
+ return TRUE;
}
+ else
+ return FALSE;
+
+ return FALSE;
}
-#endif
static void
query_editor_init (QueryEditor *editor, QueryEditorClass *klass)
@@ -132,6 +263,10 @@ query_editor_init (QueryEditor *editor, QueryEditorClass *klass)
/* allocate private structure */
editor->priv = g_new0 (QueryEditorPrivate, 1);
+ editor->priv->mode = QUERY_EDITOR_READWRITE;
+ editor->priv->batches_list = NULL;
+ editor->priv->hash = NULL;
+ editor->priv->hist_focus = NULL;
/* set up widgets */
editor->priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
@@ -139,7 +274,7 @@ query_editor_init (QueryEditor *editor, QueryEditorClass *klass)
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (editor->priv->scrolled_window),
- GTK_SHADOW_NONE);
+ GTK_SHADOW_ETCHED_OUT);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (editor->priv->scrolled_window),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start (GTK_BOX (editor), editor->priv->scrolled_window, TRUE, TRUE, 2);
@@ -153,10 +288,14 @@ query_editor_init (QueryEditor *editor, QueryEditorClass *klass)
#else
editor->priv->text = gtk_text_view_new ();
#endif
- gtk_widget_show (editor->priv->text);
gtk_container_add (GTK_CONTAINER (editor->priv->scrolled_window), editor->priv->text);
+ g_signal_connect (editor->priv->text, "event-after",
+ G_CALLBACK (event_after), editor);
+ g_signal_connect (gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->priv->text)), "changed",
+ G_CALLBACK (text_buffer_changed_cb), editor);
+
/* initialize common data */
number_of_objects++;
if (!supported_languages) {
@@ -167,6 +306,48 @@ query_editor_init (QueryEditor *editor, QueryEditorClass *klass)
}
create_tags_for_sql (editor, QUERY_EDITOR_LANGUAGE_SQL);
+
+ gtk_widget_show (editor->priv->text);
+
+ /* timeout function to update timestamps */
+ editor->priv->ts_timeout_id = 0;
+}
+
+static void
+query_editor_map (GtkWidget *widget)
+{
+ GTK_WIDGET_CLASS (parent_class)->map (widget);
+
+ if (QUERY_EDITOR (widget)->priv->mode == QUERY_EDITOR_HISTORY) {
+ GtkStyle *style;
+ style = gtk_widget_get_style (widget);
+ gtk_widget_modify_base (QUERY_EDITOR (widget)->priv->text,
+ GTK_STATE_NORMAL, &style->bg[GTK_STATE_NORMAL]);
+ }
+}
+
+static void
+hist_data_free_all (QueryEditor *editor)
+{
+ if (editor->priv->ts_timeout_id) {
+ g_source_remove (editor->priv->ts_timeout_id);
+ editor->priv->ts_timeout_id = 0;
+ }
+ if (editor->priv->batches_list) {
+ g_slist_foreach (editor->priv->batches_list, (GFunc) query_editor_history_batch_unref, NULL);
+ g_slist_free (editor->priv->batches_list);
+ editor->priv->batches_list = NULL;
+ }
+
+ if (editor->priv->hash) {
+ g_hash_table_destroy (editor->priv->hash);
+ editor->priv->hash = NULL;
+ }
+
+ if (editor->priv->hist_focus) {
+ hist_item_data_unref (editor->priv->hist_focus);
+ editor->priv->hist_focus = NULL;
+ }
}
static void
@@ -177,9 +358,8 @@ query_editor_finalize (GObject *object)
g_return_if_fail (QUERY_IS_EDITOR (editor));
/* free memory */
-#ifdef HAVE_GCONF
- gconf_client_notify_remove (gconf_client_get_default (), editor->priv->config_lid);
-#endif
+ hist_data_free_all (editor);
+
g_free (editor->priv);
editor->priv = NULL;
@@ -210,7 +390,7 @@ query_editor_get_type (void)
0,
(GInstanceInitFunc) query_editor_init
};
- type = g_type_register_static (PARENT_TYPE, "QueryEditor", &info, 0);
+ type = g_type_register_static (GTK_TYPE_VBOX, "QueryEditor", &info, 0);
}
return type;
}
@@ -237,88 +417,624 @@ query_editor_new (void)
}
/**
- * query_editor_get_editable
+ * query_editor_get_mode
* @editor: a #QueryEditor widget.
*
- * Retrieve the editable status of the given editor widget.
+ * Get @editor's mode
*
- * Returns: the editable status.
+ * Returns: @editor's mode
*/
-gboolean
-query_editor_get_editable (QueryEditor *editor)
+QueryEditorMode
+query_editor_get_mode (QueryEditor *editor)
{
- g_return_val_if_fail (QUERY_IS_EDITOR (editor), FALSE);
-
- return gtk_text_view_get_editable (GTK_TEXT_VIEW (editor->priv->text));
+ g_return_val_if_fail (QUERY_IS_EDITOR (editor), 0);
+ return editor->priv->mode;
}
/**
- * query_editor_set_editable
+ * query_editor_set_mode
* @editor: a #QueryEditor widget.
- * @editable: editable state.
+ * @mode: new mode
*
- * Set the editable state of the given editor widget.
+ * A mode change will empty the buffer.
*/
void
-query_editor_set_editable (QueryEditor *editor, gboolean editable)
+query_editor_set_mode (QueryEditor *editor, QueryEditorMode mode)
{
+ GtkTextBuffer *buffer;
+ gboolean clean = TRUE;
+
g_return_if_fail (QUERY_IS_EDITOR (editor));
- gtk_text_view_set_editable (GTK_TEXT_VIEW (editor->priv->text), editable);
+ if (editor->priv->mode == mode)
+ return;
+
+ if (((editor->priv->mode == QUERY_EDITOR_READWRITE) && (mode == QUERY_EDITOR_READONLY)) ||
+ ((editor->priv->mode == QUERY_EDITOR_READONLY) && (mode == QUERY_EDITOR_READWRITE)))
+ clean = FALSE;
+ else if (editor->priv->mode == QUERY_EDITOR_HISTORY)
+ hist_data_free_all (editor);
+
+ editor->priv->mode = mode;
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->priv->text));
+ if (clean) {
+ GtkTextIter start, end;
+ gtk_text_buffer_get_start_iter (buffer, &start);
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ gtk_text_buffer_delete (buffer, &start, &end);
+ }
+
+ switch (mode) {
+ case QUERY_EDITOR_READWRITE:
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (editor->priv->text), TRUE);
+ gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (editor->priv->text), TRUE);
+ break;
+ case QUERY_EDITOR_READONLY:
+ case QUERY_EDITOR_HISTORY:
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (editor->priv->text), FALSE);
+ gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (editor->priv->text), FALSE);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (mode == QUERY_EDITOR_HISTORY) {
+ GtkStyle *style;
+ style = gtk_widget_get_style ((GtkWidget*) editor);
+ gtk_widget_modify_base (editor->priv->text,
+ GTK_STATE_NORMAL, &style->bg[GTK_STATE_NORMAL]);
+
+ editor->priv->hash = g_hash_table_new_full (NULL, NULL, NULL,
+ (GDestroyNotify) hist_item_data_unref);
+ }
+ else {
+ gtk_widget_modify_base (editor->priv->text,
+ GTK_STATE_NORMAL, NULL);
+ }
}
/**
- * query_editor_get_highlight
+ * query_editor_set_text
* @editor: a #QueryEditor widget.
+ * @text: text to display in the editor.
+ * @len: length of @text, or -1.
*
- * Retrieve the highlighting status of the given editor widget.
+ * Set the contents of the given editor widget.
+ */
+void
+query_editor_set_text (QueryEditor *editor, const gchar *text)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+
+ g_return_if_fail (QUERY_IS_EDITOR (editor));
+ g_return_if_fail (editor->priv->mode != QUERY_EDITOR_HISTORY);
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->priv->text));
+ gtk_text_buffer_get_start_iter (buffer, &start);
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ gtk_text_buffer_delete (buffer, &start, &end);
+
+ if (text) {
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ gtk_text_buffer_insert (buffer, &end, text, -1);
+ }
+}
+
+static void
+focus_on_hist_data (QueryEditor *editor, HistItemData *hdata)
+{
+ if (editor->priv->hist_focus) {
+ if (editor->priv->hist_focus == hdata)
+ return;
+ if (editor->priv->hist_focus->item)
+ g_object_set (G_OBJECT (editor->priv->hist_focus->tag),
+ "foreground-set", TRUE, NULL);
+ else {
+ /* un-highlight all the batch */
+ GSList *list;
+ for (list = editor->priv->hist_focus->batch->hist_items; list; list = list->next) {
+ HistItemData *hd;
+ hd = g_hash_table_lookup (editor->priv->hash, list->data);
+ g_object_set (G_OBJECT (hd->tag),
+ "foreground-set", TRUE, NULL);
+ }
+ }
+ hist_item_data_unref (editor->priv->hist_focus);
+ editor->priv->hist_focus = NULL;
+ }
+
+ if (hdata) {
+ GtkTextBuffer *buffer;
+ GtkTextIter iter;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->priv->text));
+ editor->priv->hist_focus = hist_item_data_ref (hdata);
+ if (hdata->item)
+ g_object_set (G_OBJECT (hdata->tag),
+ "foreground-set", FALSE, NULL);
+ else {
+ /* highlight all the batch */
+ GSList *list;
+ for (list = hdata->batch->hist_items; list; list = list->next) {
+ HistItemData *hd;
+ hd = g_hash_table_lookup (editor->priv->hash, list->data);
+ g_object_set (G_OBJECT (hd->tag),
+ "foreground-set", FALSE, NULL);
+ }
+ }
+
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter, hdata->start_mark);
+ gtk_text_buffer_place_cursor (buffer, &iter);
+ gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW (editor->priv->text), hdata->start_mark);
+ }
+
+ g_signal_emit (editor, query_editor_signals[CHANGED], 0);
+}
+
+const char *
+get_date_format (time_t time, gint *out_timer_secs)
+{
+ static char timebuf[200];
+ GTimeVal now;
+ unsigned long diff, tmp;
+
+ *out_timer_secs = 60;
+ g_get_current_time (&now);
+
+ if (now.tv_sec < time)
+ return _("In the future:\n");
+
+ diff = now.tv_sec - time;
+ if (diff < 60)
+ return _("Less than a minute ago:\n");
+
+ /* Turn it into minutes */
+ tmp = diff / 60;
+ if (tmp < 60) {
+ snprintf (timebuf, sizeof(timebuf), ngettext ("%lu minute ago:\n",
+ "%lu minutes ago:\n", tmp), tmp);
+ return timebuf;
+ }
+ /* Turn it into hours */
+ tmp = diff / 3600;
+ if (tmp < 24) {
+ snprintf (timebuf, sizeof(timebuf), _("%lu hours ago\n"), tmp);
+ *out_timer_secs = 3600;
+ return timebuf;
+ }
+ /* Turn it into days */
+ tmp = diff / 86400;
+ snprintf (timebuf, sizeof(timebuf), _("%lu days ago:\n"), tmp);
+ *out_timer_secs = 86400;
+ return timebuf;
+}
+
+/**
+ * query_editor_start_history_batch
+ * @editor: a #QueryEditor widget.
+ * @hist_batch: a #QueryEditorHistoryBatch to add, or %NULL
*
- * Returns: the highlighting status.
+ * @hist_hash ref is _NOT_ stolen here
*/
-gboolean
-query_editor_get_highlight (QueryEditor *editor)
+void
+query_editor_start_history_batch (QueryEditor *editor, QueryEditorHistoryBatch *hist_batch)
{
- g_return_val_if_fail (QUERY_IS_EDITOR (editor), FALSE);
+ GtkTextIter iter;
+ GtkTextBuffer *buffer;
+ GtkTextTag *tag;
+ HistItemData *hdata;
+ gboolean empty = FALSE;
-#ifdef HAVE_GTKSOURCEVIEW
- return gtk_source_buffer_get_highlight_syntax (
- GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->priv->text))));
-#else
- return FALSE;
-#endif
+ g_return_if_fail (QUERY_IS_EDITOR (editor));
+ g_return_if_fail (editor->priv->mode == QUERY_EDITOR_HISTORY);
+
+ if (!hist_batch) {
+ GTimeVal run_time = {0, 0};
+ empty = TRUE;
+
+ hist_batch = query_editor_history_batch_new (run_time);
+ }
+
+ /* update editor->priv->insert_into_batch */
+ if (editor->priv->insert_into_batch)
+ query_editor_history_batch_unref (editor->priv->insert_into_batch);
+ editor->priv->insert_into_batch = query_editor_history_batch_ref (hist_batch);
+ editor->priv->batches_list = g_slist_prepend (editor->priv->batches_list,
+ query_editor_history_batch_ref (hist_batch));
+
+ /* new HistItemData */
+ hdata = hist_item_data_new ();
+ hdata->batch = query_editor_history_batch_ref (hist_batch);
+ hdata->item = NULL;
+ g_hash_table_insert (editor->priv->hash, hist_batch, hdata);
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->priv->text));
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+
+ /* mark start of insertion */
+ hdata->start_mark = gtk_text_buffer_create_mark (buffer, NULL, &iter, TRUE);
+
+ /* new tag */
+ tag = gtk_text_buffer_create_tag (buffer, NULL,
+ "pixels-below-lines", 3,
+ "foreground", "black",
+ "weight", PANGO_WEIGHT_BOLD, NULL);
+ hdata->tag = g_object_ref (tag);
+ g_hash_table_insert (editor->priv->hash, tag, hist_item_data_ref (hdata));
+
+ if (!empty) {
+ /* insert text */
+ gint timer_res;
+ gtk_text_buffer_insert_with_tags (buffer, &iter,
+ get_date_format (hist_batch->run_time.tv_sec, &timer_res),
+ -1, tag, NULL);
+ }
+
+ /* mark end of insertion */
+ hdata->end_mark = gtk_text_buffer_create_mark (buffer, NULL, &iter, TRUE);
+
+ if (empty)
+ query_editor_history_batch_unref (hist_batch);
+
+ /* add timout to 1 sec. */
+ editor->priv->ts_timeout_id = g_timeout_add_seconds (60,
+ (GSourceFunc) timestamps_update_cb, editor);
+}
+
+static gboolean
+timestamps_update_cb (QueryEditor *editor)
+{
+ GSList *list;
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+ gboolean timer_changed = FALSE;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->priv->text));
+ for (list = editor->priv->batches_list; list; list = list->next) {
+ QueryEditorHistoryBatch *batch;
+ batch = (QueryEditorHistoryBatch*) list->data;
+ if (batch->run_time.tv_sec != 0) {
+ HistItemData *hdata;
+ hdata = g_hash_table_lookup (editor->priv->hash, batch);
+
+ /* delete current text */
+ gtk_text_buffer_get_iter_at_mark (buffer, &start, hdata->start_mark);
+ gtk_text_buffer_get_iter_at_mark (buffer, &end, hdata->end_mark);
+ gtk_text_buffer_delete (buffer, &start, &end);
+
+ /* insert text */
+ gint timer_res;
+ gtk_text_buffer_get_iter_at_mark (buffer, &start, hdata->start_mark);
+ gtk_text_buffer_insert_with_tags (buffer, &start,
+ get_date_format (batch->run_time.tv_sec, &timer_res),
+ -1, hdata->tag, NULL);
+ gtk_text_buffer_delete_mark (buffer, hdata->end_mark);
+ hdata->end_mark = gtk_text_buffer_create_mark (buffer, NULL, &start, TRUE);
+
+ if (! timer_changed) {
+ /* modify timer */
+ g_source_remove (editor->priv->ts_timeout_id);
+ editor->priv->ts_timeout_id = g_timeout_add_seconds (timer_res,
+ (GSourceFunc) timestamps_update_cb, editor);
+ timer_changed = TRUE;
+ }
+ }
+ }
+ return TRUE; /* don't remove timeout */
}
/**
- * query_editor_set_highlight
+ * query_editor_add_history_item
* @editor: a #QueryEditor widget.
- * @highlight: highlighting status.
+ * @hist_item: a #QueryEditorHistoryItem to add, or %NULL
*
- * Set the highlighting status on the given editor widget.
+ * Adds some text. @text_data is usefull only if @editor's mode is HISTORY, it will be ignored
+ * otherwise.
+ *
+ * Returns: the position of the added text chunk, or %0 if mode is not HISTORY
*/
void
-query_editor_set_highlight (QueryEditor *editor, gboolean highlight)
+query_editor_add_history_item (QueryEditor *editor, QueryEditorHistoryItem *hist_item)
{
+ GtkTextIter iter;
+ GtkTextBuffer *buffer;
+ GtkTextTag *tag;
+ HistItemData *hdata;
+
g_return_if_fail (QUERY_IS_EDITOR (editor));
+ g_return_if_fail (editor->priv->mode == QUERY_EDITOR_HISTORY);
+ g_return_if_fail (hist_item);
+ g_return_if_fail (hist_item->sql);
-#ifdef HAVE_GTKSOURCEVIEW
- gtk_source_buffer_set_highlight_syntax (
- GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->priv->text))), highlight);
-#endif
+ /* new HistItemData */
+ hdata = hist_item_data_new ();
+ hdata->batch = NULL;
+ hdata->item = query_editor_history_item_ref (hist_item);
+ g_hash_table_insert (editor->priv->hash, hist_item, hdata);
+
+ if (!editor->priv->insert_into_batch)
+ query_editor_start_history_batch (editor, NULL);
+
+ query_editor_history_batch_add_item (editor->priv->insert_into_batch, hist_item);
+ hdata->batch = query_editor_history_batch_ref (editor->priv->insert_into_batch);
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->priv->text));
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+
+
+ tag = gtk_text_buffer_create_tag (buffer, NULL,
+ "scale", PANGO_SCALE_SMALL,
+ "foreground", "gray",
+ "foreground-set", TRUE, NULL);
+ hdata->tag = g_object_ref (tag);
+ g_hash_table_insert (editor->priv->hash, tag, hist_item_data_ref (hdata));
+
+ /* mark start of insertion */
+ hdata->start_mark = gtk_text_buffer_create_mark (buffer, NULL, &iter, TRUE);
+
+ /* insert text */
+ gchar *sql, *tmp1, *tmp2;
+ sql = g_strdup (hist_item->sql);
+ for (tmp1 = sql; (*tmp1 == ' ') || (*tmp1 == '\n') || (*tmp1 == '\t'); tmp1 ++);
+ for (tmp2 = sql + (strlen (sql) - 1);
+ (tmp2 > tmp1) && ((*tmp2 == ' ') || (*tmp2 == '\n') || (*tmp2 == '\t'));
+ tmp2--)
+ *tmp2 = 0;
+ gtk_text_buffer_insert_with_tags (buffer, &iter, tmp1, -1, tag, NULL);
+ gtk_text_buffer_insert_with_tags (buffer, &iter, "\n", 1, tag, NULL);
+ g_free (sql);
+
+ /* mark end of insertion */
+ hdata->end_mark = gtk_text_buffer_create_mark (buffer, NULL, &iter, TRUE);
+
+ focus_on_hist_data (editor, hdata);
+ gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (editor->priv->text),
+ &iter, 0., FALSE, 0., 0.);
}
/**
- * query_editor_set_text
+ * query_editor_get_current_history_item
* @editor: a #QueryEditor widget.
- * @text: text to display in the editor.
- * @len: length of @text.
*
- * Set the contents of the given editor widget.
+ * Get the current selected #QueryEditorHistoryItem
+ * passed to query_editor_add_history_item().
+ *
+ * Returns: a #QueryEditorHistoryItem pointer, or %NULL
+ */
+QueryEditorHistoryItem *
+query_editor_get_current_history_item (QueryEditor *editor)
+{
+ g_return_val_if_fail (QUERY_IS_EDITOR (editor), NULL);
+ g_return_val_if_fail (editor->priv->mode == QUERY_EDITOR_HISTORY, NULL);
+
+ if (editor->priv->hist_focus)
+ return editor->priv->hist_focus->item;
+ else
+ return NULL;
+}
+
+/**
+ * query_editor_get_current_history_batch
+ * @editor: a #QueryEditor widget.
+ *
+ * Get the current selected #QueryEditorHistoryBatch if the selection is not on
+ * a #QueryEditorHistoryItem, but on the #QueryEditorHistoryBatch which was last
+ * set by a call to query_editor_start_history_batch().
+ *
+ * Returns: a #QueryEditorHistoryItem pointer, or %NULL
+ */
+QueryEditorHistoryBatch *
+query_editor_get_current_history_batch (QueryEditor *editor)
+{
+ g_return_val_if_fail (QUERY_IS_EDITOR (editor), NULL);
+ g_return_val_if_fail (editor->priv->mode == QUERY_EDITOR_HISTORY, NULL);
+
+ if (editor->priv->hist_focus && !editor->priv->hist_focus->item)
+ return editor->priv->hist_focus->batch;
+ else
+ return NULL;
+}
+
+
+/**
+ * query_editor_del_current_history_item
+ * @editor: a #QueryEditor widget.
+ *
+ * Deletes the text associated to the current selection, usefull only if @editor's mode is HISTORY
+ */
+void
+query_editor_del_current_history_item (QueryEditor *editor)
+{
+ HistItemData *hdata, *focus;
+ GtkTextBuffer *buffer;
+
+ g_return_if_fail (QUERY_IS_EDITOR (editor));
+ g_return_if_fail (editor->priv->mode == QUERY_EDITOR_HISTORY);
+
+ if (!editor->priv->hist_focus)
+ return;
+ hdata = editor->priv->hist_focus;
+ if (!hdata->item)
+ return;
+
+ focus = get_next_hist_data (editor, hdata);
+ if (focus)
+ focus_on_hist_data (editor, focus);
+ else
+ focus_on_hist_data (editor, get_prev_hist_data (editor, hdata));
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->priv->text));
+
+ /* handle GtkTextBuffer's deletion */
+ GtkTextIter start, end;
+ gtk_text_buffer_get_iter_at_mark (buffer, &start, hdata->start_mark);
+ gtk_text_buffer_get_iter_at_mark (buffer, &end, hdata->end_mark);
+ gtk_text_buffer_delete (buffer, &start, &end);
+ gtk_text_buffer_delete_mark (buffer, hdata->start_mark);
+ gtk_text_buffer_delete_mark (buffer, hdata->end_mark);
+
+ hist_item_data_ref (hdata);
+ g_hash_table_remove (editor->priv->hash, hdata->item);
+ g_hash_table_remove (editor->priv->hash, hdata->tag);
+
+ if (hdata->batch) {
+ query_editor_history_batch_del_item (hdata->batch, hdata->item);
+ if (! hdata->batch->hist_items) {
+ /* remove hdata->batch */
+ HistItemData *remhdata;
+
+ editor->priv->batches_list = g_slist_remove (editor->priv->batches_list, hdata->batch);
+ query_editor_history_batch_unref (hdata->batch);
+
+ remhdata = g_hash_table_lookup (editor->priv->hash, hdata->batch);
+ gtk_text_buffer_get_iter_at_mark (buffer, &start, remhdata->start_mark);
+ gtk_text_buffer_get_iter_at_mark (buffer, &end, remhdata->end_mark);
+ gtk_text_buffer_delete (buffer, &start, &end);
+ gtk_text_buffer_delete_mark (buffer, remhdata->start_mark);
+ gtk_text_buffer_delete_mark (buffer, remhdata->end_mark);
+
+ g_hash_table_remove (editor->priv->hash, remhdata->batch);
+ g_hash_table_remove (editor->priv->hash, remhdata->tag);
+
+ if (editor->priv->insert_into_batch == hdata->batch) {
+ query_editor_history_batch_unref (editor->priv->insert_into_batch);
+ editor->priv->insert_into_batch = NULL;
+ }
+ }
+ }
+ hist_item_data_unref (hdata);
+}
+
+/**
+ * query_editor_del_history_batch
+ * @editor: a #QueryEditor
+ * @batch: a #QueryEditorHistoryBatch
+ *
+ * Deletes all regarding @batch.
*/
void
-query_editor_set_text (QueryEditor *editor, const gchar *text, gint len)
+query_editor_del_history_batch (QueryEditor *editor, QueryEditorHistoryBatch *batch)
{
+ GtkTextBuffer *buffer;
+ GSList *list;
+ HistItemData *hdata;
+ GtkTextIter start, end;
+ HistItemData *focus;
+ gint i;
+
g_return_if_fail (QUERY_IS_EDITOR (editor));
- gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->priv->text)),
- text, len);
+ g_return_if_fail (editor->priv->mode == QUERY_EDITOR_HISTORY);
+ g_return_if_fail (batch);
+ i = g_slist_index (editor->priv->batches_list, batch);
+ g_return_if_fail (i >= 0);
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->priv->text));
+
+ /* compute new focus */
+ if (i > 0) {
+ focus = NULL;
+ list = g_slist_nth (editor->priv->batches_list, i - 1);
+ focus = g_hash_table_lookup (editor->priv->hash, list->data);
+ }
+ focus_on_hist_data (editor, focus);
+
+ /* remove all history items */
+ for (list = batch->hist_items; list; list = batch->hist_items) {
+ hdata = g_hash_table_lookup (editor->priv->hash, list->data);
+ g_assert (hdata);
+
+ gtk_text_buffer_get_iter_at_mark (buffer, &start, hdata->start_mark);
+ gtk_text_buffer_get_iter_at_mark (buffer, &end, hdata->end_mark);
+ gtk_text_buffer_delete (buffer, &start, &end);
+ gtk_text_buffer_delete_mark (buffer, hdata->start_mark);
+ gtk_text_buffer_delete_mark (buffer, hdata->end_mark);
+
+ g_hash_table_remove (editor->priv->hash, hdata->item);
+ g_hash_table_remove (editor->priv->hash, hdata->tag);
+ query_editor_history_batch_del_item (batch, (QueryEditorHistoryItem*) list->data);
+ }
+
+ /* remove batch */
+ editor->priv->batches_list = g_slist_remove (editor->priv->batches_list, batch);
+ query_editor_history_batch_unref (batch);
+
+ hdata = g_hash_table_lookup (editor->priv->hash, batch);
+ gtk_text_buffer_get_iter_at_mark (buffer, &start, hdata->start_mark);
+ gtk_text_buffer_get_iter_at_mark (buffer, &end, hdata->end_mark);
+ gtk_text_buffer_delete (buffer, &start, &end);
+ gtk_text_buffer_delete_mark (buffer, hdata->start_mark);
+ gtk_text_buffer_delete_mark (buffer, hdata->end_mark);
+
+ if (editor->priv->insert_into_batch == batch) {
+ query_editor_history_batch_unref (editor->priv->insert_into_batch);
+ editor->priv->insert_into_batch = NULL;
+ }
+
+ g_hash_table_remove (editor->priv->hash, hdata->batch);
+ g_hash_table_remove (editor->priv->hash, hdata->tag);
+}
+
+static HistItemData *
+get_next_hist_data (QueryEditor *editor, HistItemData *hdata)
+{
+ GSList *node;
+ g_return_val_if_fail (hdata, NULL);
+ g_assert (hdata->batch);
+
+ if (hdata->item) {
+ node = g_slist_find (hdata->batch->hist_items, hdata->item);
+ g_assert (node);
+ node = node->next;
+ if (node)
+ return g_hash_table_lookup (editor->priv->hash, node->data);
+ }
+ else
+ if (hdata->batch->hist_items)
+ return g_hash_table_lookup (editor->priv->hash, hdata->batch->hist_items->data);
+
+ /* move on to the next batch if any */
+ gint i;
+ i = g_slist_index (editor->priv->batches_list, hdata->batch);
+ if (i > 0) {
+ node = g_slist_nth (editor->priv->batches_list, i-1);
+ hdata = g_hash_table_lookup (editor->priv->hash, node->data);
+ return get_next_hist_data (editor, hdata);
+ }
+ return NULL;
+}
+
+static HistItemData *
+get_prev_hist_data (QueryEditor *editor, HistItemData *hdata)
+{
+ GSList *node;
+ gint i;
+ g_return_val_if_fail (hdata, NULL);
+ g_assert (hdata->batch);
+
+ if (hdata->item) {
+ node = g_slist_find (hdata->batch->hist_items, hdata->item);
+ g_assert (node);
+ i = g_slist_position (hdata->batch->hist_items, node);
+ if (i > 0) {
+ node = g_slist_nth (hdata->batch->hist_items, i - 1);
+ return g_hash_table_lookup (editor->priv->hash, node->data);
+ }
+ }
+
+ /* move to the previous batch, if any */
+ node = g_slist_find (editor->priv->batches_list, hdata->batch);
+ node = node->next;
+ while (node) {
+ QueryEditorHistoryBatch *b;
+ b = (QueryEditorHistoryBatch*) node->data;
+ GSList *l;
+ l = g_slist_last (b->hist_items);
+ if (l)
+ return g_hash_table_lookup (editor->priv->hash, l->data);
+ node = node->next;
+ }
+
+ return NULL;
}
/**
@@ -367,7 +1083,7 @@ query_editor_load_from_file (QueryEditor *editor, const gchar *filename)
g_return_val_if_fail (filename != NULL, FALSE);
if (g_file_get_contents (filename, &contents, NULL, NULL)) {
- query_editor_set_text (editor, contents, -1);
+ query_editor_set_text (editor, contents);
g_free (contents);
}
else
@@ -449,3 +1165,136 @@ query_editor_paste_clipboard (QueryEditor *editor)
NULL,
gtk_text_view_get_editable (GTK_TEXT_VIEW (editor->priv->text)));
}
+
+/*
+ * QueryEditorHistoryBatch
+ */
+QueryEditorHistoryBatch *
+query_editor_history_batch_new (GTimeVal run_time)
+{
+ QueryEditorHistoryBatch *qib;
+
+ qib = g_new0 (QueryEditorHistoryBatch, 1);
+ qib->ref_count = 1;
+ qib->run_time = run_time;
+ return qib;
+}
+
+QueryEditorHistoryBatch *
+query_editor_history_batch_ref (QueryEditorHistoryBatch *qib)
+{
+ g_return_val_if_fail (qib, NULL);
+ qib->ref_count++;
+ return qib;
+}
+
+void
+query_editor_history_batch_unref (QueryEditorHistoryBatch *qib)
+{
+ g_return_if_fail (qib);
+ qib->ref_count--;
+ if (qib->ref_count <= 0) {
+ if (qib->hist_items) {
+ g_slist_foreach (qib->hist_items, (GFunc) query_editor_history_item_unref, NULL);
+ g_slist_free (qib->hist_items);
+ }
+ g_free (qib);
+ }
+}
+
+void
+query_editor_history_batch_add_item (QueryEditorHistoryBatch *qib, QueryEditorHistoryItem *qih)
+{
+ g_return_if_fail (qib);
+ g_return_if_fail (qih);
+ qib->hist_items = g_slist_append (qib->hist_items, query_editor_history_item_ref (qih));
+}
+
+void
+query_editor_history_batch_del_item (QueryEditorHistoryBatch *qib, QueryEditorHistoryItem *qih)
+{
+ g_return_if_fail (qib);
+ g_return_if_fail (qih);
+ qib->hist_items = g_slist_remove (qib->hist_items, qih);
+ query_editor_history_item_unref (qih);
+}
+
+/*
+ * QueryEditorHistoryItem
+ */
+QueryEditorHistoryItem *
+query_editor_history_item_new (const gchar *sql, GdaSet *params, GObject *result)
+{
+ QueryEditorHistoryItem *qih;
+
+ g_return_val_if_fail (sql, NULL);
+
+ qih = g_new0 (QueryEditorHistoryItem, 1);
+ qih->ref_count = 1;
+ qih->sql = g_strdup (sql);
+ if (params)
+ qih->params = gda_set_copy (params);
+ if (result)
+ qih->result = g_object_ref (result);
+
+ return qih;
+}
+
+QueryEditorHistoryItem *
+query_editor_history_item_ref (QueryEditorHistoryItem *qih)
+{
+ g_return_val_if_fail (qih, NULL);
+ qih->ref_count++;
+ return qih;
+}
+
+void
+query_editor_history_item_unref (QueryEditorHistoryItem *qih)
+{
+ g_return_if_fail (qih);
+ qih->ref_count--;
+ if (qih->ref_count <= 0) {
+ g_free (qih->sql);
+ if (qih->params)
+ g_object_unref (qih->params);
+ if (qih->result)
+ g_object_unref (qih->result);
+ g_free (qih);
+ }
+}
+
+/*
+ * HistItemData
+ */
+static HistItemData *
+hist_item_data_new (void)
+{
+ HistItemData *hdata;
+ hdata = g_new0 (HistItemData, 1);
+ hdata->ref_count = 1;
+ return hdata;
+}
+
+static HistItemData *
+hist_item_data_ref (HistItemData *hdata)
+{
+ g_return_val_if_fail (hdata, NULL);
+ hdata->ref_count ++;
+ return hdata;
+}
+
+static void
+hist_item_data_unref (HistItemData *hdata)
+{
+ g_return_if_fail (hdata);
+ hdata->ref_count --;
+ if (hdata->ref_count <= 0) {
+ if (hdata->batch)
+ query_editor_history_batch_unref (hdata->batch);
+ if (hdata->item)
+ query_editor_history_item_unref (hdata->item);
+ if (hdata->tag)
+ g_object_unref (hdata->tag);
+ g_free (hdata);
+ }
+}
diff --git a/tools/browser/query-exec/query-editor.h b/tools/browser/query-exec/query-editor.h
index e55e386..d92dab1 100644
--- a/tools/browser/query-exec/query-editor.h
+++ b/tools/browser/query-exec/query-editor.h
@@ -25,6 +25,7 @@
#define __QUERY_EDITOR_H__
#include <gtk/gtkvbox.h>
+#include <libgda/libgda.h>
G_BEGIN_DECLS
@@ -47,19 +48,59 @@ struct _QueryEditorClass {
GtkVBoxClass parent_class;
/* signals */
- void (* text_changed) (QueryEditor editor);
+ void (* changed) (QueryEditor editor);
};
-#define QUERY_EDITOR_LANGUAGE_SQL "sql"
+/*
+ * Query history item
+ */
+typedef struct {
+ gchar *sql;
+ GdaSet *params;
+ GObject *result;
+
+ gint ref_count;
+} QueryEditorHistoryItem;
+
+QueryEditorHistoryItem *query_editor_history_item_new (const gchar *sql, GdaSet *params, GObject *result);
+QueryEditorHistoryItem *query_editor_history_item_ref (QueryEditorHistoryItem *qih);
+void query_editor_history_item_unref (QueryEditorHistoryItem *qih);
+
+/*
+ * Query history batch
+ */
+typedef struct {
+ GTimeVal run_time;
+ GSList *hist_items; /* list of QueryEditorHistoryItem, ref held here */
+
+ gint ref_count;
+} QueryEditorHistoryBatch;
+
+QueryEditorHistoryBatch *query_editor_history_batch_new (GTimeVal run_time);
+QueryEditorHistoryBatch *query_editor_history_batch_ref (QueryEditorHistoryBatch *qib);
+void query_editor_history_batch_unref (QueryEditorHistoryBatch *qib);
+void query_editor_history_batch_add_item (QueryEditorHistoryBatch *qib,
+ QueryEditorHistoryItem *qih);
+void query_editor_history_batch_del_item (QueryEditorHistoryBatch *qib,
+ QueryEditorHistoryItem *qih);
+
+/*
+ * Editor modes
+ */
+typedef enum {
+ QUERY_EDITOR_READWRITE,
+ QUERY_EDITOR_READONLY,
+ QUERY_EDITOR_HISTORY
+} QueryEditorMode;
+
GType query_editor_get_type (void) G_GNUC_CONST;
GtkWidget *query_editor_new (void);
-gboolean query_editor_get_editable (QueryEditor *editor);
-void query_editor_set_editable (QueryEditor *editor, gboolean editable);
-gboolean query_editor_get_highlight (QueryEditor *editor);
-void query_editor_set_highlight (QueryEditor *editor, gboolean highlight);
-void query_editor_set_text (QueryEditor *editor, const gchar *text, gint len);
+/* common API */
+void query_editor_set_mode (QueryEditor *editor, QueryEditorMode mode);
+QueryEditorMode query_editor_get_mode (QueryEditor *editor);
+
gchar *query_editor_get_all_text (QueryEditor *editor);
gboolean query_editor_load_from_file (QueryEditor *editor, const gchar *filename);
gboolean query_editor_save_to_file (QueryEditor *editor, const gchar *filename);
@@ -68,6 +109,18 @@ void query_editor_copy_clipboard (QueryEditor *editor);
void query_editor_cut_clipboard (QueryEditor *editor);
void query_editor_paste_clipboard (QueryEditor *editor);
+/* normal editor's API */
+void query_editor_set_text (QueryEditor *editor, const gchar *text);
+
+/* history API */
+void query_editor_start_history_batch (QueryEditor *editor, QueryEditorHistoryBatch *hist_batch);
+void query_editor_add_history_item (QueryEditor *editor, QueryEditorHistoryItem *hist_item);
+QueryEditorHistoryItem *query_editor_get_current_history_item (QueryEditor *editor);
+QueryEditorHistoryBatch *query_editor_get_current_history_batch (QueryEditor *editor);
+
+void query_editor_del_current_history_item (QueryEditor *editor);
+void query_editor_del_history_batch (QueryEditor *editor, QueryEditorHistoryBatch *batch);
+
G_END_DECLS
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]