Advertisement
Guest User

Untitled

a guest
Jul 28th, 2017
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Vala 8.82 KB | None | 0 0
  1. /*
  2.  *  Copyright 2010 Colomban Wendling  <ban(at)herbesfolles(dot)org>
  3.  *
  4.  *  This program is free software; you can redistribute it and/or modify
  5.  *  it under the terms of the GNU General Public License as published by
  6.  *  the Free Software Foundation; either version 2 of the License, or
  7.  *  (at your option) any later version.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *  GNU General Public License for more details.
  13.  *
  14.  *  You should have received a copy of the GNU General Public License
  15.  *  along with this program; if not, write to the Free Software
  16.  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17.  *
  18.  */
  19.  
  20. using Geany;
  21. using Gtk;
  22. using Postgres;
  23.  
  24.  
  25. /* Geany sets these variables at plugin registration time */
  26. public Plugin       geany_plugin;
  27. public Data         geany_data;
  28. public Functions    geany_functions;
  29.  
  30. //public Database plugin_db_connection;
  31. /*----------------- Plugin-global variables (prefix with G_) -----------------*/
  32.  
  33. private GLib.SList<unowned Gtk.Widget>  G_destroy_widget_stack;
  34.  
  35.  
  36. /*---------------------------- Begin plugin code ----------------------------*/
  37. public class PluginQueryWindow : Gtk.Window {
  38.     private TreeView    results;
  39.     private TextView    text_view;
  40.     private int col_count;
  41.     private bool    data_loaded;
  42.     private Database    pgconn;
  43.     private Result  pgresult;
  44.     public PluginQueryWindow () {
  45.        
  46.         // setup some basic window properties
  47.         this.title = "Query Window";
  48.         this.position = WindowPosition.CENTER;
  49.         this.set_default_size (800, 500);
  50.         this.position = WindowPosition.CENTER;
  51.         this.data_loaded = false;
  52.        
  53.         // build the toolbar buttons
  54.         var open_button = new ToolButton.from_stock (Gtk.Stock.OPEN);
  55.         open_button.label = "Open Query";
  56.         open_button.clicked.connect(()=>{this.on_open_clicked();});
  57.        
  58.         var connect_button = new ToolButton.from_stock (Gtk.Stock.CONNECT);
  59.         connect_button.label = "Connect to DB";
  60.         connect_button.clicked.connect(
  61.             ()=>{
  62.                 this.db_connect("localhost","webuser","webuser","fulcrum");
  63.             }
  64.         );
  65.        
  66.         // TODO: make execute button ONLY execute selected query text
  67.         var execute_button = new ToolButton.from_stock (Gtk.Stock.EXECUTE);
  68.         execute_button.label = "Execute Query";
  69.         execute_button.clicked.connect(()=>{this.perform_query();});
  70.        
  71.         var close_button = new ToolButton.from_stock (Gtk.Stock.CLOSE);
  72.         close_button.label = "Close Window";
  73.         close_button.clicked.connect(()=>{this.destroy();});
  74.    
  75.         // create the toolbar and add the buttons
  76.         var toolbar = new Toolbar ();
  77.         toolbar.set_style(ToolbarStyle.BOTH);
  78.         toolbar.add (open_button);
  79.         toolbar.add (connect_button);
  80.         toolbar.add (execute_button);
  81.         toolbar.add (close_button);
  82.  
  83.         // query entry area
  84.         this.text_view = new TextView ();
  85.        
  86.         // TODO: set initial query to selected text from current document
  87.         this.text_view.buffer.text = "select * from projects;";
  88.         var query_scroll = new ScrolledWindow (null, null);
  89.         query_scroll.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
  90.         query_scroll.add (this.text_view);
  91.  
  92.         // query results area
  93.         this.results = new TreeView ();
  94.         var result_scroll = new ScrolledWindow (null, null);
  95.         result_scroll.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
  96.         result_scroll.add (this.results);
  97.         //setup_treeview (results);
  98.        
  99.         // now pack it all
  100.         var vbox = new VBox(false, 0);
  101.         vbox.pack_start (toolbar, false, true, 0);
  102.         vbox.pack_start (query_scroll, true, true, 0);
  103.         vbox.pack_start (result_scroll, true, true, 0);
  104.        
  105.         this.add (vbox);
  106.        
  107.         // TODO: read db config from the project
  108.         this.db_connect("localhost","webuser","webuser","fulcrum");
  109.         this.destroy.connect (()=>{this.plugin_db_disconnect();});
  110.         this.show_all ();
  111.     }
  112.    
  113.     private void on_open_clicked () {
  114.         var file_chooser = new FileChooserDialog ("Open File", this,
  115.                                       FileChooserAction.OPEN,
  116.                                       Stock.CANCEL, ResponseType.CANCEL,
  117.                                       Stock.OPEN, ResponseType.ACCEPT);
  118.         if (file_chooser.run () == ResponseType.ACCEPT) {
  119.             open_file (file_chooser.get_filename ());
  120.         }
  121.         file_chooser.destroy ();
  122.     }
  123.  
  124.     private void open_file (string filename) {
  125.         try {
  126.             string text;
  127.             FileUtils.get_contents (filename, out text);
  128.             this.text_view.buffer.text = text;
  129.         } catch (Error e) {
  130.             stderr.printf ("Error: %s\n", e.message);
  131.         }
  132.     }
  133.    
  134.     private void perform_query()
  135.     {
  136.         //this.pgresult = this.pgconn.exec ("select * from pg_database");
  137.         string query = this.text_view.buffer.text;
  138.         Msgwin.status_add("trying to execute query: "+query);
  139.         if(query != "")
  140.         {
  141.             // TODO: capture query errors
  142.             this.pgresult = this.pgconn.exec(query);
  143.             this.update_results();
  144.  
  145.         }
  146.         else
  147.         {
  148.            
  149.             // TODO: replace errors with real popups
  150.             var window = new Window ();
  151.             window.title = "Error";
  152.             window.set_default_size (300, 50);
  153.             window.position = WindowPosition.CENTER;
  154.             var button = new Button.with_label ("Please enter a query");
  155.  
  156.             window.add (button);
  157.             window.show_all ();
  158.         }
  159.     }
  160.    
  161.     private void update_results()
  162.     {
  163.         if(this.data_loaded)
  164.         {
  165.             for (int i = this.col_count; i >=0; i--)
  166.             {
  167.                 this.results.remove_column(this.results.get_column(i));
  168.             }
  169.         }
  170.        
  171.         int nFields = this.pgresult.get_n_fields ();
  172.         Type[] cols = new Type[nFields];
  173.         for (int i = 0; i < nFields; i++)
  174.         {
  175.             cols[i] = typeof (string);
  176.         }
  177.         var listmodel = new ListStore.newv(cols);
  178.         this.results.set_model (listmodel);
  179.  
  180.         for (int i = 0; i < nFields; i++)
  181.         {
  182.             this.results.insert_column_with_attributes (
  183.                 -1,
  184.                 this.pgresult.get_field_name(i),
  185.                 new CellRendererText (),
  186.                 "text",
  187.                 0
  188.             );
  189.             var column =  this.results.get_column(i);
  190.             column.set_resizable(true);
  191.             Msgwin.status_add("Setting "+column.get_title()+" to resizable");
  192.         }
  193.        
  194.         TreeIter iter;
  195.         for (int i = 0; i < this.pgresult.get_n_tuples(); i++) {
  196.             listmodel.append (out iter);
  197.             for (int j = 0; j < nFields; j++) {
  198.                 // BUG: Fails to insert actual result value into TreeView
  199.                
  200.                 //listmodel.set_value(iter,j,"Mike");
  201.                 // ^^ This works! 'Mike' shows up in every col
  202.                
  203.                 //Msgwin.status_add("Result:"+(string)this.pgresult.get_value (i, j));
  204.                 // ^^ This works! the value from the db is printed to the status window
  205.                 string myval = (string)this.pgresult.get_value (i, j);
  206.                 listmodel.set_value(iter,j,myval);
  207.                 // ^^ this does NOT work. The column number is put into every column, rather than the value
  208.                
  209.                 //listmodel.set_value(iter,j,("mike"+(string)this.pgresult.get_value (i, j)));
  210.                 // ^^ this does NOT work. The string 'mike' plus the column number (mike1,mike2) is put into every column
  211.        
  212.             }
  213.             stdout.printf ("\n");
  214.         }
  215.         this.data_loaded = true;
  216.         this.col_count = nFields;
  217.     }
  218.    
  219.     private bool db_connect(string host,string user,string password, string dbname)
  220.     {
  221.         string conninfo = "";
  222.  
  223.         if(host != "")
  224.             conninfo += " host="+host;
  225.  
  226.         if(user != "")
  227.             conninfo += " user="+user;
  228.  
  229.         if(password != "")
  230.             conninfo += " password="+password;
  231.  
  232.         if(dbname != "")
  233.             conninfo += " dbname="+dbname;
  234.  
  235.         this.pgconn = Postgres.connect_db (conninfo);
  236.         if (pgconn.get_status () != ConnectionStatus.OK) {
  237.             stderr.printf ("Connection to database failed: %s", this.pgconn.get_error_message ());
  238.             return false;
  239.         }
  240.         return true;
  241.     }
  242.  
  243.     private int plugin_db_disconnect()
  244.     {
  245.         // TODO: make disconnect actually work
  246.         return 1;
  247.     }
  248. }
  249.  
  250.  
  251. /*------------------------- Plugin registration & co -------------------------*/
  252.  
  253. public int plugin_version_check (int abi_version)
  254. {
  255.     return Plugin.version_check (abi_version, 185);
  256. }
  257.  
  258. public void plugin_set_info (Plugin.Info info)
  259. {
  260.     info.set (
  261.         "Database Plugin",
  262.         "A plugin for Geany to view databases",
  263.         "0.1",
  264.         "Mike Thorn"
  265.     );
  266. }
  267.  
  268. public void plugin_init (Geany.Data data)
  269. {
  270.     Gtk.MenuItem item;
  271.    
  272.     unowned Gtk.MenuShell? menu = Ui.lookup_widget (geany_data.main_widgets.window,
  273.                                                     "menu_document1_menu") as Gtk.MenuShell;
  274.     if (menu == null) {
  275.         menu = geany_data.main_widgets.tools_menu;
  276.     } else {
  277.         item = new Gtk.SeparatorMenuItem ();
  278.         menu.append (item);
  279.         G_destroy_widget_stack.append (item);
  280.         item.show ();
  281.     }
  282.    
  283.  
  284.    
  285.     item = new Gtk.MenuItem.with_label ("Query Window");
  286.     item.activate.connect (() => {
  287.         //Document.editor.insert_text_block("mike test",0,0,0,false);
  288.         new PluginQueryWindow();
  289.     });
  290.     menu.append (item);
  291.     G_destroy_widget_stack.append (item);
  292.     item.show ();
  293.    
  294.     // TODO: Add keybindings
  295. }
  296.  
  297. public void plugin_cleanup ()
  298. {
  299.     foreach (var w in G_destroy_widget_stack) {
  300.         w.destroy ();
  301.     }
  302. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement