1. Abdelrahman Ghanem
  2. rgsum

Source

rgsum / RGSum.rb

#!/usr/bin/ruby
# coding: utf-8
# Gtk Gui
# Author: Abdelrahman ghanem <abom.jdev@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

require 'gtk2'
require 'lib/sum'

$KCODE="u"
$VERSION="0.1.7-beta"
$ICON=Gdk::Pixbuf.new("icons/calc.png")

class SumWindow < Gtk::Window
  
  def initialize
    super Gtk::Window::TOPLEVEL
    self.title="RGSum"
    self.set_default_size(400, 300)
    self.icon_list=[$ICON]
    self.border_width=5
    @sumlib=Sum.new
    #menubar:
    menubar=Gtk::MenuBar.new
    #file
    filemenu=Gtk::Menu.new
    file=Gtk::MenuItem.new("_File")
    file.submenu=filemenu
    menubar.append(file)
    @action_open=Gtk::Action.new('','Open',nil,Gtk::Stock::OPEN)
    @file_sep=Gtk::SeparatorMenuItem.new
    @action_quit=Gtk::Action.new('','Quit',nil,Gtk::Stock::QUIT)
    filemenu.append(@action_open.create_menu_item)
    filemenu.append(@file_sep)
    filemenu.append(@action_quit.create_menu_item)
    #edit
    editmenu=Gtk::Menu.new
    edit=Gtk::MenuItem.new("_Edit")
    edit.submenu=editmenu
    menubar.append(edit)
    @action_sum=Gtk::Action.new('','Sum',nil,Gtk::Stock::EXECUTE)
    @action_stop=Gtk::Action.new('','Stop',nil,Gtk::Stock::STOP)
    @sum_sep=Gtk::SeparatorMenuItem.new
    @action_copy=Gtk::Action.new('','Copy',nil,Gtk::Stock::COPY)
    @action_paste=Gtk::Action.new('','Paste',nil,Gtk::Stock::PASTE)
    @copy_sep=Gtk::SeparatorMenuItem.new
    @action_save=Gtk::Action.new('','Save',nil,Gtk::Stock::SAVE)
    @save = @action_save.create_menu_item
    editmenu.append(@action_sum.create_menu_item)
    editmenu.append(@action_stop.create_menu_item)
    editmenu.append(@sum_sep)
    editmenu.append(@action_copy.create_menu_item)
    editmenu.append(@action_paste.create_menu_item)
    editmenu.append(@copy_sep)
    editmenu.append(@action_save.create_menu_item)
    #about
    helpmenu=Gtk::Menu.new
    help=Gtk::MenuItem.new("_Help")
    help.submenu=helpmenu
    menubar.append(help)
    @action_about=Gtk::Action.new('','About',nil,Gtk::Stock::ABOUT)
    helpmenu.append(@action_about.create_menu_item)
    
    #tool bar
    toolbar=Gtk::Toolbar.new
    toolbar.insert(0,@action_open.create_tool_item)
    toolbar.insert(1,@action_sum.create_tool_item)
    toolbar.insert(2,@action_stop.create_tool_item)
    toolbar.insert(3,@action_copy.create_tool_item)
    toolbar.insert(4,@action_paste.create_tool_item)
    toolbar.insert(5,@action_save.create_tool_item)
    #file
    @lblfile=Gtk::Label.new("File:")
    @entryfile=Gtk::Entry.new
    @entryfile.editable=false
    @hboxfile=Gtk::HBox.new(false,2)
    @hboxfile.pack_start(@lblfile,false,false,1)
    @hboxfile.pack_start(@entryfile,true,true,1)   
    #algorithm type
    @lbl=Gtk::Label.new("Select a file and the algorithm type:")
    @combotype=Gtk::ComboBox.new
    @combotype.append_text("md5")
    @combotype.append_text("sha1")
    @combotype.append_text("sha224")
    @combotype.append_text("sha256")
    @combotype.append_text("sha384")
    @combotype.append_text("sha512")
    @combotype.active=0
    @chbox=Gtk::HBox.new(false,2)
    @chbox.pack_start(@lbl,false,false,1)
    @chbox.pack_start(@combotype,false,true,1)
    #result
    @lblre=Gtk::Label.new("Result:")
    @lblre.set_alignment(0,0)
    @txtrebuf=Gtk::TextBuffer.new
    @txtre=Gtk::TextView.new(@txtrebuf)
    @txtre.editable=false
    @txtre.wrap_mode=Gtk::TextTag::WRAP_CHAR
    @hboxre=Gtk::HBox.new(false,2)
    @hboxre.pack_start(@lblre,false,false,1)
    @hboxre.pack_start(@txtre,true,true,1)
    #compare with
    @lblcompare=Gtk::Label.new("Compare with:")
    @entrycompare=Gtk::Entry.new
    
    @error = Gtk::Stock::DIALOG_ERROR #'icons/error.png'
    @warning = Gtk::Stock::DIALOG_WARNING #'icons/warning.png'
    @ok = Gtk::Stock::APPLY #'icons/ok.png'
    
    @imagecompare = Gtk::Image.new
    @imagecompare.stock = @warning
    #@btncompare=Gtk::Button.new("_Compare")
    @hboxcompare=Gtk::HBox.new(false, 3)
    @hboxcompare.pack_start(@lblcompare,false,false,1)
    @hboxcompare.pack_start(@entrycompare,true,true,1)
    @hboxcompare.pack_start(@imagecompare,false,false,1)
    #progress bar
    @hboxpb = Gtk::HBox.new(false, 3)
    @btnshowdetails = Gtk::Button.new
    @btnshowdetails.image = Gtk::Image.new
    @btnshowdetails.image.stock = Gtk::Stock::GO_DOWN
    
    @btnhidedetails = Gtk::Button.new
    @btnhidedetails.image = Gtk::Image.new
    @btnhidedetails.image.stock = Gtk::Stock::GO_UP
    
    @pb=Gtk::ProgressBar.new
    @hboxpb.pack_start(@btnshowdetails,false,false,1)
    @hboxpb.pack_start(@btnhidedetails,false,false,1)
    @hboxpb.pack_start(@pb,true,true,1)
    
    #details widget
    #model
    @iterators = []
    @list_store = Gtk::ListStore.new(String, String)
    ['Filename:', 'Size:',
     'Reading speed:', 'Reading:',
     'Elapsed:', 'Estimated:'].zip(['']*6).each do |label, value|
      iter = @list_store.append
      iter[0] = label
      iter[1] = value
      @iterators << iter
    end
    #tree view and scroll window
    @treedetails = Gtk::TreeView.new(@list_store)
    @scrollwindow = Gtk::ScrolledWindow.new
    @scrollwindow.shadow_type = Gtk::SHADOW_OUT
    @scrollwindow.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC)
    @scrollwindow.add_with_viewport(@treedetails)
    
    @renderer = Gtk::CellRendererText.new
    labels = Gtk::TreeViewColumn.new('', @renderer, :text=>0)
    details = Gtk::TreeViewColumn.new('Details', @renderer, :text=>1)
    
    @treedetails.append_column(labels)
    @treedetails.append_column(details)

    #status bar
    @statusbar = Gtk::Statusbar.new
    
    #main vbox, and  vertical paned
    @vbox = Gtk::VBox.new
    @vpaned = Gtk::VPaned.new
    @mainvbox=Gtk::VBox.new(false,7)
    @mainvbox.pack_start(menubar,false,false,0)
    @mainvbox.pack_start(toolbar,false,false,0)
    
    @vbox.pack_start(@hboxfile,false,false,1)    
    @vbox.pack_start(@chbox,false,false,1)    
    @vbox.pack_start(@hboxre,true,true,1)
    @vbox.pack_start(@hboxcompare,false,false,1) 
    @vbox.pack_start(@hboxpb,false,false,1)
    @mainvbox.pack_start(@vpaned,true,true,1)
    @vpaned.add1(@vbox)
    @vpaned.add2(@scrollwindow)
    @mainvbox.pack_start(@statusbar,false,false,1)
    
    add(@mainvbox)
    
    #connect
    signal_connect("destroy"){quit}
    signal_connect("delete-event"){quit}
    @action_quit.signal_connect("activate") {quit}
    @action_sum.signal_connect("activate") {do_sum}
    @action_stop.signal_connect("activate") {do_stop}
    @action_copy.signal_connect("activate") {cb_copy}
    @action_paste.signal_connect("activate") {cb_paste}
    @action_about.signal_connect("activate") {show_about}
    @action_open.signal_connect("activate") {browse}
    @action_save.signal_connect("activate") {save}
    @btnshowdetails.signal_connect("clicked"){show_details}
    @btnhidedetails.signal_connect("clicked"){hide_details}
    @entrycompare.signal_connect("changed") {do_compare}
    enable_comp(true)
    
    @statusbar.push(1, 'Ready')
  end

  def quit
    do_stop
    Gtk.main_quit
  end
  
  def show_details
    @btnshowdetails.hide
    @btnhidedetails.show
    @scrollwindow.show
  end
  
  def hide_details
    @btnshowdetails.show
    @btnhidedetails.hide
    @scrollwindow.hide
  end
  
  def hide_pb
    @hboxpb.hide
    @btnhidedetails.hide
    @scrollwindow.hide
  end
  
  def show_pb
    @hboxpb.show
    @btnshowdetails.show
  end
  
  def enable_comp(bool)
    if bool
      @action_sum.sensitive=true
      @action_copy.sensitive=true
      @action_paste.sensitive=true
      @action_open.sensitive=true
      @action_stop.sensitive=false
      @action_save.sensitive=true
      #@btncompare.sensitive=true
    else
      @action_sum.sensitive=false
      @action_copy.sensitive=false
      @action_paste.sensitive=false
      @action_open.sensitive=false
      @action_stop.sensitive=true
      @action_save.sensitive=false
      #@btncompare.sensitive=false
    end
  end
  
  def browse
    fdialog=Gtk::FileChooserDialog.new("Select File:",
                                       self,Gtk::FileChooser::ACTION_OPEN,
                                       nil,
                                       [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
                                       [Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT])
    if fdialog.run==Gtk::Dialog::RESPONSE_ACCEPT
      @entryfile.text=fdialog.filename
    end
    fdialog.destroy
  end
  
  def do_sum
    return if @entryfile.text.empty?
    enable_comp(false)
    show_pb
    @txtrebuf.text="Now calculating......."
    @sumlib.algo=@combotype.active_text
    @sumlib.filename=@entryfile.text
    size=@sumlib.size.to_f
    @iterators[0][1] = File.basename(@sumlib.filename)
    @iterators[1][1] = @sumlib.to_size(size*100)
    stime = Time.now
    @sumlib.sum do |i|
      @pb.fraction=i/size
      @pb.text="#{(@pb.fraction*100).to_s.split('.')[0]}%"
      @elapsed_time = @sumlib.to_time(@sumlib.elapsed)
      @speed = "#{@sumlib.to_size(@sumlib.read_rate)}/sec"
      @estimated_time = @sumlib.to_time(@sumlib.estimated)
      @iterators[2][1] = @speed
      @iterators[3][1] = @sumlib.to_size(i*100)
      @iterators[4][1] = @elapsed_time
      @iterators[5][1] = @estimated_time
      while Gtk.events_pending?
        Gtk.main_iteration
      end
    end
    if !@sumlib.stopped?
      @statusbar.push(1, "Done | Elapsed: #{@elapsed_time}")
    end
    @txtrebuf.text=@sumlib.result
    hide_pb
    enable_comp(true)
  end
  
  def do_stop
    @sumlib.stop=true
  end
  
  def cb_copy
    #select all
    @txtrebuf.place_cursor(@txtrebuf.start_iter)
    @txtrebuf.move_mark(@txtrebuf.selection_bound,@txtrebuf.end_iter)
    #copy
    @txtre.signal_emit("copy-clipboard")
    #deselect all
    @txtrebuf.place_cursor(@txtrebuf.start_iter)
    @txtrebuf.move_mark(@txtrebuf.selection_bound,@txtrebuf.start_iter)   
  end
  
  def cb_paste
    @entrycompare.text=""
    @entrycompare.signal_emit("paste-clipboard")
  end

  def save
    sum=@txtrebuf.text
    file=@entryfile.text
    return if sum.empty? or file.empty? or sum=='stopped.'
    sdialog=Gtk::FileChooserDialog.new("Choose file:",
                                       self,Gtk::FileChooser::ACTION_SAVE,
                                       nil,
                                       [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
                                       [Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT])
    if sdialog.run==Gtk::Dialog::RESPONSE_ACCEPT
      data=@txtrebuf.text+' '+File.basename(@entryfile.text)
      file=sdialog.filename+".#{@combotype.active_text}sum"
      File.open(file,'w+'){|f|f.write(data)}
    end
    sdialog.destroy
  end
  
  def msg(message,type)
    case type
    when 'e' : type=Gtk::MessageDialog::ERROR
    when 'i' : type=Gtk::MessageDialog::INFO
    end
    msgd=Gtk::MessageDialog.new(self,
                                Gtk::Dialog::DESTROY_WITH_PARENT,
                                type,
                                Gtk::MessageDialog::BUTTONS_OK,
                                message)
    msgd.run
    msgd.destroy
  end
    
  def do_compare
    if @txtrebuf.text.empty? or @entrycompare.text.empty?
      @imagecompare.stock = @warning
      return
    end
    if @txtrebuf.text==@entrycompare.text
      @imagecompare.stock = @ok
    else
      @imagecompare.stock = @error
    end
  end
  
  def show_about
    aboutd=Gtk::AboutDialog.new
    aboutd.program_name="RGSum"
    aboutd.version="0.1.7"
    aboutd.logo=$ICON
    aboutd.copyright="(c) 2009-2010 Abdelrahman Ghanem"
    aboutd.comments="Calculates [md5,sha1,sha224,sha256,sha380,sha512]"
    aboutd.license=IO::read('COPYING')
    aboutd.authors=["Abdelrahmn Ghanem <abom.jdev@gmail.com>"]
    aboutd.website="http://www.programming-fr34ks.net"
    aboutd.website_label="www.programming-fr34ks.net"
    aboutd.run
    aboutd.destroy
  end
  
end

if $0==__FILE__
  swin=SumWindow.new
  swin.show_all #move it to initailize()?
  swin.hide_pb
  Gtk.main
end