| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728 |
- //
- // SqlEditor.cs - writen in C# using GTK#
- //
- // Authors:
- // Daniel Morgan <[email protected]>
- // Rodrigo Moya <[email protected]>
- //
- // (c)copyright 2002 Daniel Morgan
- // (c)copyright 2002 Rodrigo Moya
- //
- // SqlEditorSharp is based on the gnome-db-sql-editor.c in libgnomedb.
- // SqlEditorSharp falls under the GPL license and is included
- // in SQL# For GTK#. SQL# For GTK# is a database query tool for Mono.
- //
- namespace SqlEditorSharp
- {
- using System;
- using Gtk;
- using Gdk;
- using GLib;
- using System.Collections;
- using System.IO;
- using System.Text;
- using System.Runtime.InteropServices;
- using System.Diagnostics;
- using Mono.Data.SqlSharp.Gui.GtkSharp;
- /// <summary> SqlEditor Class</summary>
- /// <remarks>
- /// </remarks>
- public class SqlEditorSharp : Gtk.VBox
- {
- // Fields
- // text tags for TextTagTable in TextBuffer
- private TextTag freecomment_tag;
- private TextTag linecomment_tag;
- private TextTag singlequotedconstant_tag;
- private TextTag sql_tag;
- private TextTag normaltext_tag;
- // determine if something has changed beyond a line
- // updating one line is faster than the whole buffer
- //private int line_last_changed;
- //private int last_freecomment_count;
- // settings
- private bool use_hi_lighting;
- private string family;
- // widgets
- private ScrolledWindow scroll;
- private TextView sqlTextView;
- private TextBuffer sqlTextBuffer;
- private EditorTab tab = null;
- // Constructors
- public SqlEditorSharp() : base(false, 4) {
- scroll = new ScrolledWindow (
- new Adjustment (0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
- new Adjustment (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
- scroll.HscrollbarPolicy = Gtk.PolicyType.Automatic;
- scroll.VscrollbarPolicy = Gtk.PolicyType.Automatic;
- scroll.ShadowType = Gtk.ShadowType.In;
- this.PackStart (scroll, true, true, 0);
- // default font famly for SQL editor
- family = "courier";
- // other default settings
- use_hi_lighting = false;
- // create text tag table
- TextTagTable textTagTable = new TextTagTable ();
- // anything else is normaltext
- normaltext_tag = new TextTag ("normaltext");
- normaltext_tag.Family = family;
- normaltext_tag.Foreground = "black";
- normaltext_tag.Style = Pango.Style.Normal;
- textTagTable.Add (normaltext_tag);
-
- // SQL Keywords - SELECT FROM WHERE, etc
- sql_tag = new TextTag ("sql");
- sql_tag.Family = family;
- sql_tag.Foreground = "blue";
- sql_tag.Style = Pango.Style.Normal;
- textTagTable.Add (sql_tag);
- // c like free comment - used within a SQL statement
- freecomment_tag = new TextTag ("freecomment");
- freecomment_tag.Family = family;
- freecomment_tag.Foreground = "darkgreen";
- freecomment_tag.Style = Pango.Style.Italic;
- textTagTable.Add (freecomment_tag);
- // c++ like line comment, but using two hyphens
- linecomment_tag = new TextTag ("linecomment");
- linecomment_tag.Family = family;
- linecomment_tag.Foreground = "darkgreen";
- linecomment_tag.Style = Pango.Style.Italic;
- textTagTable.Add (linecomment_tag);
- /* single quoted constant - WHERE COL1 = 'ABC' */
- singlequotedconstant_tag = new TextTag ("singlequotedconstant");
- singlequotedconstant_tag.Family = family;
- singlequotedconstant_tag.Foreground = "red";
- singlequotedconstant_tag.Style = Pango.Style.Normal;
- textTagTable.Add (singlequotedconstant_tag);
- // create TextBuffer and TextView
- sqlTextBuffer = new TextBuffer (textTagTable);
- sqlTextView = new TextView (sqlTextBuffer);
- // allow it to be edited
- sqlTextView.Editable = true;
- //line_last_changed = -1;
- //last_freecomment_count = -1;
- // attach OnTextChanged callback function
- // to "changed" signal so we can do something
- // when the text has changed in the buffer
- sqlTextBuffer.Changed += new EventHandler (OnTextChanged);
- // add the TextView to the ScrolledWindow
- scroll.Add (sqlTextView);
- }
- // Public Properties
- public TextBuffer Buffer {
- get {
- return sqlTextBuffer;
- }
- }
- public TextView View {
- get {
- return sqlTextView;
- }
- }
- public EditorTab Tab {
- get {
- return tab;
- }
- set {
- tab = value;
- }
- }
- public bool UseSyntaxHiLighting {
- get {
- return use_hi_lighting;
- }
- set {
- use_hi_lighting = value;
- }
- }
- // Private Methods
- void OnTextChanged (object o, EventArgs args)
- {
- if(tab != null)
- tab.label.Text = tab.basefilename + " *";
- SqlSharpGtk.DebugWriteLine ("[[[[[ Syntax Hi-Light Text BEGIN ]]]]]");
- if (use_hi_lighting == true) {
- SyntaxHiLightText ();
- }
-
- SqlSharpGtk.DebugWriteLine ("[[[[[ Syntax Hi-Light Text END ]]]]]\n");
- }
- void SyntaxHiLightText ()
- {
- TextIter start_iter, end_iter,
- iter, insert_iter;
- TextIter match_start1, match_end1,
- match_start2, match_end2;
- int char_count = 0;
- int hyphen = 0, single_quotes = 0;
- string text = String.Empty;
- int i = 0, start_con = 0, end_con = 0;
- //int line = 0;
- //int freecomment_count = 0;
- int start_word = -1;
- TextMark insert_mark;
- char ch = ' ';
- insert_mark = sqlTextBuffer.InsertMark;
- sqlTextBuffer.GetIterAtMark (out insert_iter, insert_mark);
- //line = insert_iter.Line;
-
- /* get the starting and ending text iterators */
- sqlTextBuffer.GetIterAtOffset (out start_iter, 0);
- char_count = sqlTextBuffer.CharCount;
- sqlTextBuffer.GetIterAtOffset (out end_iter, char_count);
-
- SqlSharpGtk.DebugWriteLine ("char_count: " + char_count);
-
- /* since line is not same - redo all */
- //if (line != line_last_changed) {
- /* remove all previously applied tags */
- sqlTextBuffer.RemoveAllTags (start_iter, end_iter);
- /* apply the entire buffer to the normaltext tag */
- sqlTextBuffer.ApplyTag (normaltext_tag, start_iter, end_iter);
- //}
- //else { /* just worry about current insertion line */
- // /* get start iter */
- // if (insert_iter.StartsLine () == true) {
- // start_iter = insert_iter;
- // }
- // else {
- // start_iter = insert_iter;
- // start_iter.LineOffset = 0;
- // }
- // /* get end iter */
- // end_iter.ForwardToLineEnd ();
- // char_count = start_iter.CharsInLine;
- //
- // /* remove all previously applied tags */
- // sqlTextBuffer.RemoveAllTags (start_iter, end_iter);
- //
- // /* apply the entire buffer to the normaltext tag */
- // sqlTextBuffer.ApplyTag (normaltext_tag,
- // start_iter, end_iter);
- //
- // /* get the starting and ending text iterators */
- // sqlTextBuffer.GetIterAtOffset (out start_iter, 0);
- // char_count = sqlTextBuffer.CharCount;
- // sqlTextBuffer.GetIterAtOffset (out end_iter, char_count);
- //}
- /* ------------------------------------
- * Free Comments (sort of like c style)
- * ------------------------------------
- * except in SQL, a c like comment occurs within
- * a SQL statement
- */
- match_start1 = start_iter; // dummy
- match_end1 = end_iter; // dummy
- match_start2 = start_iter; // dummy
- match_end2 = end_iter; // dummy
- while (start_iter.IsEnd == false) {
- // FIXME: match_start1, match_end1, end_iter
- // need to be set to have ref in front
- // Problem with TextIter's ForwardSearch()
- // in GTK# (not GTK+)
- if (start_iter.ForwardSearch (
- "/*",
- TextSearchFlags.TextOnly,
- out match_start1,
- out match_end1,
- end_iter) == true) {
- /* beginning of free comment found */
- //freecomment_count++;
- // FIXME: fix match_start2, match_end2, end_iter
- // with ref if front
- if (match_end1.ForwardSearch (
- "*/",
- TextSearchFlags.TextOnly,
- out match_start2,
- out match_end2,
- end_iter) == true) {
- // ending of free comment found,
- // now hi-light comment
- sqlTextBuffer.ApplyTag (
- freecomment_tag,
- match_start1,
- match_end2);
- match_end2.ForwardChars (1);
- start_iter = match_end2;
- }
- else {
- // if no end found,
- // hi-light to the end,
- // to let the user know
- // the ending asterisk slash is missing
- ApplyTag (
- freecomment_tag,
- normaltext_tag,
- match_start1,
- end_iter);
- break;
- }
- }
- else
- break;
- }
- /* if free comments is different than last time,
- * invalidate line_last_changed - causes
- * a complete redo (instead hi-lighting just the current line -
- * do the whole buffer)
- * THIS IS JUST AN ATTEMPT FOR SPEED
- */
- //if (freecomment_count != last_freecomment_count) {
- // line_last_changed = -1;
- //}
- /*********************************************************************
- * See if the following needs hi-lighting:
- * - Line Comments (sort of like C++ slash slash comments
- * but uses hypen hyphen and it is based at the beginning of a line)
- * - Single-Quoted Constants ( WHERE COL1 = 'ABC' )
- * - SQL keywords (SELECT, FROM, WHERE, UPDATE, etc)
- *********************************************************************/
- //if (line != line_last_changed) {
- sqlTextBuffer.GetIterAtOffset (out start_iter, 0);
- //}
- //else {
- // if (insert_iter.StartsLine () == true) {
- // start_iter = insert_iter;
- // }
- // else {
- // start_iter = insert_iter;
- // start_iter.LineOffset = 0;
- // }
- //}
- // get starting and ending iters
- // and character count of line
- char_count = sqlTextBuffer.CharCount;
- sqlTextBuffer.GetIterAtOffset (out end_iter, char_count);
-
- // for each line, look for:
- // line comments, constants, and keywoards
- do {
- iter = start_iter;
- iter.ForwardToLineEnd ();
- text = sqlTextBuffer.GetText (
- start_iter, iter, false);
- // look for line comment
- char_count = start_iter.CharsInLine;
- hyphen = 0;
- for (i = 0; i < char_count - 1; i++) {
- switch (text[i]) {
- case '-':
- if (hyphen == 1) {
- hyphen = 2;
- // line comment found
- i = char_count;
- ApplyTag (
- linecomment_tag,
- normaltext_tag,
- start_iter,
- iter);
- }
- else {
- hyphen = 1;
- }
- break;
- case ' ':
- // continue
- break;
- default:
- // this line is not line commented
- i = char_count; // break out of for loop
- break;
- }
- }
- // if not line commented,
- // look for singled quoted constants
- // and keywords
- if (hyphen < 2) {
- if (start_iter.IsEnd == true)
- break; // break out of for loop
- start_word = -1;
- single_quotes = 0;
- LookForSingleQuotesAndWords (
- ref start_iter,
- text, char_count,
- ref start_word,
- ref single_quotes,
- ref start_con,
- ref end_con);
- }
-
- } while (start_iter.ForwardLine () == true);
-
- // POOR ATTEMPTS AT SPEED - last_freecomment_count
- // and line_last_changed
- //
- //last_freecomment_count = freecomment_count;
- //line_last_changed = line;
- }
- void LookForSingleQuotesAndWords (ref TextIter start_iter,
- string text, int char_count,
- ref int start_word, ref int single_quotes,
- ref int start_con, ref int end_con)
- {
- TextIter match_start1, match_end1;
- int i;
- char ch;
- for (i = 0; i < char_count; i++) {
- match_start1 = start_iter;
- match_end1 = start_iter;
-
- if (match_end1.IsEnd == true)
- break;
- if (CharHasTag (start_iter,
- freecomment_tag, i)
- == false) {
-
- if (single_quotes == 0 &&
- start_word == -1) {
- ch = text[i];
- if (ch == '\'') {
- single_quotes = 1;
- start_con = i + 1;
- }
- else if (Char.IsLetter (ch)) {
- start_word = i;
- }
- else {
- // continue
- }
- }
- else if (single_quotes == 1) {
- ch = text[i];
- switch (ch) {
- case '\'':
- // single quoted constant
- end_con = i;
-
- // get starting and
- // ending of constant
- // excluding quotes
- ApplyTagOffsets (
- start_iter,
- start_con, i,
- singlequotedconstant_tag,
- normaltext_tag);
- single_quotes = 0;
- break;
- default:
- break;
- }
- }
- else if (start_word != -1) {
- ch = text[i];
- // is character alphabetic, numeric, or '_'
- if (Char.IsLetterOrDigit (ch) ||
- ch == '_') {
- // continue
- }
- else {
- // using start_word
- // and i offsets,
- // get word
- if (IsTextSQL (text, start_word, i)) {
- // word is a SQL keyword,
- // hi-light word
- ApplyTagOffsets (
- start_iter,
- start_word, i,
- sql_tag,
- normaltext_tag);
- }
- start_word = -1;
- switch (text[i]) {
- case '\'':
- single_quotes = 1;
- start_con = i + 1;
- break;
- default:
- break;
- }
- }
- }
- }
- }
- if( start_word != -1) {
- if (IsTextSQL (text, start_word, i)) {
- // word is a SQL keyword,
- // hi-light word
- ApplyTagOffsets(
- start_iter,
- start_word, i,
- sql_tag,
- normaltext_tag);
- }
- }
- }
- void ApplyTag ( TextTag apply_tag, TextTag remove_tag,
- TextIter start_iter, TextIter end_iter )
- {
- #if DEBUG
- DebugText(start_iter, end_iter, "ApplyTag() " +
- "remove: " + remove_tag.Name +
- " apply: " + apply_tag.Name);
- #endif // DEBUG
- sqlTextBuffer.RemoveTag (
- remove_tag,
- start_iter, end_iter);
- sqlTextBuffer.ApplyTag (
- apply_tag,
- start_iter, end_iter);
- }
- void ApplyTagOffsets (TextIter start_iter,
- int start_offset, int end_offset,
- TextTag apply_tag,
- TextTag remove_tag)
- {
- TextIter begin_iter, end_iter;
-
- begin_iter = start_iter;
- end_iter = start_iter;
- begin_iter.LineOffset = start_offset;
- end_iter.LineOffset = end_offset;
-
- #if DEBUG
- DebugText(start_iter, end_iter, "ApplyTagOffsets() " +
- "remove: " + remove_tag.Name +
- " apply: " + apply_tag.Name +
- " start: " + start_offset.ToString() +
- " end: " + end_offset.ToString());
- #endif
- sqlTextBuffer.RemoveTag (remove_tag,
- begin_iter, end_iter);
- sqlTextBuffer.ApplyTag (apply_tag,
- begin_iter, end_iter);
- }
- /* is word a SQL keyword? */
- bool IsTextSQL (string text, int begin, int end)
- {
- string keyword = "";
- int i;
- int text_len;
- if(text.Equals(String.Empty))
- return false;
- if(begin < 0)
- return false;
- if(end < 2)
- return false;
- if(begin >= end)
- return false;
- text_len = end - begin;
- if(text_len < 1)
- return false;
- #if DEBUG
- SqlSharpGtk.DebugWriteLine("IsTextSQL - " +
- "begin: " + begin.ToString() +
- " end: " + end.ToString() +
- " text_len: " + text_len);
- SqlSharpGtk.DebugWriteLine("[TEXT BEGIN]");
- SqlSharpGtk.DebugWriteLine(text);
- SqlSharpGtk.DebugWriteLine("[TEXT END ]");
- #endif // DEBUG
- for (i = 0; sql_keywords[i] != String.Empty; i++) {
- if(text_len == sql_keywords[i].Length) {
-
- SqlSharpGtk.DebugWriteLine(
- "Test length: " + text_len +
- " keyword: " + keyword);
-
- try {
- keyword = text.Substring (begin, text_len);
- }
- catch(ArgumentOutOfRangeException a) {
- Console.WriteLine ("Internal Error: SqlSharpGtk: text.Substring() ArgumentOutOfRange");
- }
- keyword = keyword.ToUpper();
- if(keyword.Equals (sql_keywords [i]))
- return true;
- }
- }
- return false;
- }
- // does the character at offset in the GtkTextIter has
- // this text tag applied?
- bool CharHasTag(TextIter iter,
- TextTag tag, int char_offset_in_line)
- {
- TextIter offset_iter;
- offset_iter = iter;
- offset_iter.LineOffset = char_offset_in_line;
-
- return offset_iter.HasTag (tag);
- }
- public void Clear()
- {
- TextIter start, end;
- start = sqlTextBuffer.StartIter;
- end = sqlTextBuffer.EndIter;
- sqlTextBuffer.Delete(start,end);
- }
- public void LoadFromFile(string inFilename)
- {
- StreamReader sr = new StreamReader(inFilename);
- Clear();
- string NextLine;
- string line;
-
- while((NextLine = sr.ReadLine()) != null) {
- line = NextLine + "\n";
- sqlTextBuffer.Insert (sqlTextBuffer.EndIter, line);
- }
- sr.Close();
- }
- public void SaveToFile(string outFilename)
- {
- TextIter start_iter, iter;
- string text;
- StreamWriter sw = null;
-
- sw = new StreamWriter(outFilename);
- sqlTextBuffer.GetIterAtOffset (out iter, 0);
- start_iter = iter;
- while (iter.ForwardLine()) {
- text = sqlTextBuffer.GetText(start_iter, iter, false);
- sw.Write(text);
- start_iter = iter;
- }
- text = sqlTextBuffer.GetText(start_iter, iter, false);
- sw.Write(text);
- sw.Close();
- sw = null;
- }
- void DebugText (TextIter iter_start, TextIter iter_end,
- string debugMessage)
- {
- #if DEBUG
- string text = sqlTextBuffer.GetText (
- iter_start, iter_end, false);
- string msg =
- "[DEBUG-TEXT]: " +
- debugMessage +
- " (" +
- text +
- ")";
- SqlSharpGtk.DebugWriteLine(msg);
- #endif // DEBUG
- }
- static readonly string[] sql_keywords =
- new string[] {
- "DELETE",
- "FROM",
- "SELECT",
- "UPDATE",
- "SET",
- "INSERT",
- "INTO",
- "VALUES",
- "WHERE",
- "COUNT",
- "SUM",
- "MAX",
- "MIN",
- "AVG",
- "DROP",
- "ALTER",
- "CREATE",
- "VIEW",
- "TABLE",
- "AS",
- "AND",
- "OR",
- "ORDER",
- "GROUP",
- "BY",
- "HAVING",
- "IS",
- "NULL",
- "NOT",
- "COMMIT",
- "ROLLBACK",
- "EXISTS",
- "IN",
- "LIKE",
- "GRANT",
- "REVOKE",
- "ON",
- "TO",
- String.Empty
- };
- }
- }
|