You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdebindings/qtruby/bin/rbqtsh

628 lines
18 KiB

#!/usr/bin/env ruby
# rbqtsh : a graphical shell for qtruby.
#
# author: Germain Garand <germain@ebooksfrance.org>
# ruby port: Alexander Kellett <lypanov@kde.org>
# license: GNU Public License v2
#
require 'stringio'
case File.basename $0
when "rbqtsh"
require 'Qt'
when "rbtdesh"
require 'Korundum'
end
include Qt
$image0_data =
["22 22 7 1",
". c None",
"# c #000000",
"b c #292c29",
"c c #5a5d5a",
"d c #838583",
"e c #c5c2c5",
"a c #ffffff",
"......................",
"....##########........",
"....#aaaaaaa#b#.......",
"....#aaaaaaa#cb#......",
"....#aaaaaaa#dcb#.....",
"....#aaaaaaa#edcb#....",
"....#aaaaaaa#aedcb#...",
"....#aaaaaaa#######...",
"....#aaaaaaaaaaaaa#...",
"....#aaaaaaaaaaaaa#...",
"....#aaaaaaaaaaaaa#...",
"....#aaaaaaaaaaaaa#...",
"....#aaaaaaaaaaaaa#...",
"....#aaaaaaaaaaaaa#...",
"....#aaaaaaaaaaaaa#...",
"....#aaaaaaaaaaaaa#...",
"....#aaaaaaaaaaaaa#...",
"....#aaaaaaaaaaaaa#...",
"....#aaaaaaaaaaaaa#...",
"....###############...",
"......................",
"......................"]
$image1_data =
["22 22 5 1",
". c None",
"# c #000000",
"c c #838100",
"a c #ffff00",
"b c #ffffff",
"......................",
"......................",
"......................",
"............####....#.",
"...........#....##.##.",
"..................###.",
".................####.",
".####...........#####.",
"#abab##########.......",
"#babababababab#.......",
"#ababababababa#.......",
"#babababababab#.......",
"#ababab###############",
"#babab##cccccccccccc##",
"#abab##cccccccccccc##.",
"#bab##cccccccccccc##..",
"#ab##cccccccccccc##...",
"#b##cccccccccccc##....",
"###cccccccccccc##.....",
"##cccccccccccc##......",
"###############.......",
"......................"]
$image2_data =
["22 22 5 1",
". c None",
"# c #000000",
"a c #838100",
"b c #c5c2c5",
"c c #cdb6d5",
"......................",
".####################.",
".#aa#bbbbbbbbbbbb#bb#.",
".#aa#bbbbbbbbbbbb#bb#.",
".#aa#bbbbbbbbbcbb####.",
".#aa#bbbccbbbbbbb#aa#.",
".#aa#bbbccbbbbbbb#aa#.",
".#aa#bbbbbbbbbbbb#aa#.",
".#aa#bbbbbbbbbbbb#aa#.",
".#aa#bbbbbbbbbbbb#aa#.",
".#aa#bbbbbbbbbbbb#aa#.",
".#aaa############aaa#.",
".#aaaaaaaaaaaaaaaaaa#.",
".#aaaaaaaaaaaaaaaaaa#.",
".#aaa#############aa#.",
".#aaa#########bbb#aa#.",
".#aaa#########bbb#aa#.",
".#aaa#########bbb#aa#.",
".#aaa#########bbb#aa#.",
".#aaa#########bbb#aa#.",
"..##################..",
"......................"]
$image3_data =
["22 22 88 2",
"Qt c None",
".2 c #000000",
".S c #08ff08",
"#v c #100810",
".U c #101010",
"#c c #101018",
".M c #181018",
"#e c #181818",
".A c #181820",
".L c #201820",
"#l c #202020",
".z c #202029",
"#m c #292029",
"#u c #292829",
"#n c #292831",
".R c #29ff29",
"#o c #312831",
".T c #313031",
"#p c #313039",
".Z c #31ff31",
"#q c #393039",
"#t c #393839",
".y c #393841",
"#s c #413841",
".o c #414041",
"#h c #4a4852",
".n c #5a505a",
"#r c #5a5962",
".I c #5ace5a",
"#b c #6a616a",
".p c #6a696a",
".x c #6a6973",
".Y c #6aff62",
".l c #736973",
".t c #7b717b",
".s c #7b7183",
".0 c #7bff7b",
".r c #837983",
".u c #83798b",
"#g c #83858b",
".v c #8b7994",
"#i c #8b858b",
".w c #8b8594",
"#j c #8b8d8b",
".8 c #8b8d94",
".m c #948d94",
"#k c #948d9c",
"#f c #949594",
".q c #94959c",
".J c #94c694",
"#d c #9c959c",
"#a c #9c95a4",
".k c #9c9d9c",
".N c #9c9da4",
".H c #9ccea4",
".K c #a49da4",
"#. c #a49dac",
".i c #a4a5a4",
".3 c #a4a5ac",
"## c #ac9dac",
".V c #aca5ac",
".d c #acaeac",
".j c #acaeb4",
".9 c #b4aeb4",
".# c #b4b6b4",
".a c #bdbebd",
".7 c #bdd6bd",
".c c #c5c6c5",
".5 c #cdc6cd",
".b c #cdcecd",
".4 c #cdced5",
".F c #d5ced5",
".G c #d5cede",
".h c #d5d6d5",
".E c #d5d6de",
".Q c #d5ffd5",
".B c #ded6de",
".1 c #ded6e6",
".g c #dedede",
".D c #dedee6",
".6 c #e6dee6",
".f c #e6e6e6",
".C c #e6e6ee",
".X c #e6ffe6",
".O c #eee6ee",
".e c #eeeeee",
".W c #f6f6f6",
".P c #ffffff",
"QtQtQtQtQtQt.#.a.b.b.b.b.c.c.a.a.d.aQtQtQtQt",
"QtQtQtQtQtQt.a.e.f.f.f.f.f.e.e.e.g.aQtQtQtQt",
"QtQtQtQtQtQt.a.c.c.c.b.b.c.c.c.c.a.cQtQtQtQt",
"QtQtQtQtQtQt.#.a.a.a.a.#.a.a.#.#.d.aQtQtQtQt",
"QtQtQtQtQt.c.d.c.a.c.c.c.a.a.a.c.#QtQtQtQtQt",
"QtQtQtQtQt.a.a.#.a.a.a.a.a.a.c.c.#QtQtQtQtQt",
"QtQtQtQtQt.a.#.c.a.a.a.a.a.c.a.c.dQtQtQtQtQt",
"QtQtQtQtQt.c.a.a.a.a.a.a.a.a.a.a.#QtQtQtQtQt",
"QtQtQtQtQt.d.b.f.g.g.g.g.g.g.h.g.i.i.jQtQtQt",
"QtQtQt.a.k.l.#.h.b.h.b.h.b.h.g.g.m.n.o.p.#Qt",
"QtQt.a.q.r.s.t.t.t.t.t.t.t.u.v.w.x.y.z.A.o.i",
"Qt.a.k.B.C.D.B.E.E.E.E.F.G.H.I.J.K.o.L.L.M.y",
".a.N.O.P.P.P.P.P.P.P.P.P.Q.R.S.R.b.v.T.A.U.L",
".V.W.P.P.P.P.P.P.P.P.P.P.X.Y.Z.0.P.1.t.A.2.L",
".3.E.4.5.4.h.E.E.g.6.D.B.D.E.7.F.4.5.8.M.2.A",
".m.9.j.V.3#..3.K#.#..i#..K#.###a.q.8#b#c.2.L",
".m.j.j#..3.K.K.K.N.K.N.N.N.N#a#d#d.w#b#c.2#e",
"#f#.#..K.N.K.N.N.N#a.k#a#d#d#d#a.m#g#b.M.2#h",
".m.3.K.K#a.k#a#d#a.k#a#d#a#d.q.m.8#i.x#c#e.d",
"#f#g#i.w#j.w#i.8.w#i.8.8.m.8.m#k.8.w#b#e#fQt",
".#.l.z.A#l.z#m#m#m#n#o#o#p#p#q#q#p#o#p#fQtQt",
"QtQt.d#r#s#s#t#p.T.T.T#u#u.z#e#e#v.o.kQtQtQt"]
class QtShellControl < TQt::MainWindow
attr_accessor :menubar, :fileMenu, :helpMenu, :toolBar, :fileName, :fileOpenAction
attr_accessor :fileSaveAction, :fileSaveAsAction, :filePrintAction, :fileExitAction
attr_accessor :helpExampleAction, :comboBox, :sessionLog, :executedLines, :printer
slots 'fileOpen()', 'fileOpen()', 'fileSave()', 'fileSaveAs()'
slots 'filePrint()', 'fileExit()', 'runSelection()', 'helpExample()'
signals 'fileNeedsEval(TQString)', 'selection(TQString)'
def initialize(*k)
super(*k)
image0 = TQt::Pixmap.new($image0_data)
image1 = TQt::Pixmap.new($image1_data)
image2 = TQt::Pixmap.new($image2_data)
image3 = TQt::Pixmap.new($image3_data)
box = VBox.new(self)
@sessionLog = TextEdit.new(box, "sessionLog")
@sessionLog.setTextFormat(TQt::RichText)
@sessionLog.setReadOnly(true)
@comboBox = ComboBox.new(box, "comboBox")
@comboBox.setEditable(true)
@comboBox.setAutoCompletion(true)
self.setCentralWidget(box)
@comboBox.setFocus
self.resize(500,300)
self.setCaption("QtRuby Shell")
def trUtf8(k)
return k
end
@fileOpenAction = TQt::Action.new(self, "fileOpenAction")
@fileOpenAction.setIconSet(TQt::IconSet.new(image1))
@fileOpenAction.setText(trUtf8("Open"))
@fileOpenAction.setMenuText(trUtf8("&Open..."))
@fileOpenAction.setAccel(KeySequence.new(trUtf8("Ctrl+O")))
@fileSaveAction = TQt::Action.new(self, "fileSaveAction")
@fileSaveAction.setIconSet(TQt::IconSet.new(image2))
@fileSaveAction.setText(trUtf8("Save"))
@fileSaveAction.setMenuText(trUtf8("&Save"))
@fileSaveAction.setAccel(KeySequence.new(trUtf8("Ctrl+S")))
@fileSaveAsAction = TQt::Action.new(self, "fileSaveAsAction")
@fileSaveAsAction.setText(trUtf8("Save As"))
@fileSaveAsAction.setMenuText(trUtf8("Save &As..."))
@fileSaveAsAction.setAccel(KeySequence.new(trUtf8("Ctrl+A")))
@filePrintAction = TQt::Action.new(self, "filePrintAction")
@filePrintAction.setIconSet(TQt::IconSet.new(image3))
@filePrintAction.setText(trUtf8("Print"))
@filePrintAction.setMenuText(trUtf8("&Print..."))
@filePrintAction.setAccel(KeySequence.new(trUtf8("Ctrl+P")))
@fileExitAction = TQt::Action.new(self, "fileExitAction")
@fileExitAction.setText(trUtf8("Exit"))
@fileExitAction.setMenuText(trUtf8("E&xit"))
@fileExitAction.setAccel(KeySequence.new(trUtf8("Ctrl+E")))
@runAction = TQt::Action.new(self, "runAction");
@runAction.setText(trUtf8("Run Selection"));
@runAction.setMenuText(trUtf8("&Run Selection"));
@runAction.setAccel(KeySequence.new(trUtf8("Ctrl+R")));
@helpExampleAction = TQt::Action.new(self, "helpExampleAction");
@helpExampleAction.setText(trUtf8("Example"));
@helpExampleAction.setMenuText(trUtf8("Examp&le"));
@helpExampleAction.setAccel(KeySequence.new(trUtf8("Ctrl+L")));
@toolBar = TQt::ToolBar.new("", self, DockTop)
@toolBar.setLabel(trUtf8("Tools"))
@fileOpenAction.addTo(toolBar)
@fileSaveAction.addTo(toolBar)
@filePrintAction.addTo(toolBar)
@menubar= TQt::MenuBar.new(self, "menubar")
@fileMenu= TQt::PopupMenu.new(self)
@fileOpenAction.addTo(fileMenu)
@fileSaveAction.addTo(fileMenu)
@fileSaveAsAction.addTo(fileMenu)
@fileMenu.insertSeparator
@filePrintAction.addTo(fileMenu)
@fileMenu.insertSeparator
@fileExitAction.addTo(fileMenu)
@menubar.insertItem(trUtf8("&File"), fileMenu)
@menubar.insertSeparator
@runMenu= TQt::PopupMenu.new(self)
@runAction.addTo(@runMenu)
@menubar.insertItem(trUtf8("Run"), @runMenu)
@menubar.insertSeparator
@helpMenu= TQt::PopupMenu.new(self)
@helpExampleAction.addTo(helpMenu)
@menubar.insertItem(trUtf8("&Help"), helpMenu)
connect(@fileOpenAction, TQ_SIGNAL('activated()'), self, TQ_SLOT('fileOpen()'))
connect(@fileSaveAction, TQ_SIGNAL('activated()'), self, TQ_SLOT('fileSave()'))
connect(@fileSaveAsAction, TQ_SIGNAL('activated()'), self, TQ_SLOT('fileSaveAs()'))
connect(@filePrintAction, TQ_SIGNAL('activated()'), self, TQ_SLOT('filePrint()'))
connect(@fileExitAction, TQ_SIGNAL('activated()'), self, TQ_SLOT('fileExit()'))
connect(@runAction, TQ_SIGNAL('activated()'), self, TQ_SLOT('runSelection()'))
connect(@helpExampleAction, TQ_SIGNAL('activated()'), self, TQ_SLOT('helpExample()'))
@executedLines = []
end
def fileOpen
fname = TQt::FileDialog::getOpenFileName(
".",
"Rbqtsh Session (*.rbqts)",
self,
"open session",
"Choose a file to open")
return if fname.nil?
emit fileNeedsEval(fname)
end
def getFileName
@fileName = TQt::FileDialog::getSaveFileName(
".",
"Rbqtsh Session (*.rbqts)",
self,
"save session",
"Choose a filename" )
unless @fileName =~ /\.rbqts$/
@fileName << ".rbqts"
end
@fileName
end
def save(fname)
file = File.new(fname, "w")
if file.nil
# TODO fix ": unknown" to give a reason
TQt::MessageBox::critical(
self,
"Error" ,
"Couldn't open #{fname} for writing: unknown",
TQt::MessageBox::Ok,
TQt::MessageBox::NoButton )
return
end
@executedLines.each {
|line|
next if line =~ /^\s*$/
line.chomp!
line << ";" unless line =~ /;\s*$/
file.puts(line)
}
file.close
end
def fileSave
return if emptySession
fname = @fileName || getFileName
return if fname.nil?
save fname
end
def fileSaveAs(cond = 0)
return if emptySession
fname = getFileName
return if fname.nil?
ret = nil
if File.exists(fname)
cond += 1
ret = TQt::MessageBox::warning(
self,
"Warning" ,
"File exists, overwrite ?",
TQt::MessageBox::Yes,
TQt::MessageBox::No )
else
cond = 0
end
fileSaveAs(cond) if (cond == 0) and ret == TQt::MessageBox::No
save(fname)
end
def filePrint()
margin = 10
pageNo = 1
emptySession() and return
printer = TQt::Printer.new()
if printer.setup(self)
statusBar().message( "Printing..." )
p = TQt::Painter.new()
if ! p.begin( printer )
statusBar().message( "An error occured..." )
return
end
p.setFont( sessionLog.font() )
yPos = 0
fm = p.fontMetrics
metrics = TQt::PaintDeviceMetrics.new( printer )
for i in 0..@executedLines.length-1
if margin + yPos > metrics.height() - margin
msg ="Printing (page "+ ++pageNo + ")..."
statusBar().message( msg )
printer.newPage()
yPos = 0
end
p.drawText( margin, margin + yPos,
metrics.width(), fm.lineSpacing(),
ExpandTabs | DontClip,
"#{@executedLines[ i ]}" )
yPos = yPos + fm.lineSpacing()
end
p.end()
statusBar().message( "Printing completed", 3000 )
else
statusBar().message( "Printing aborted", 3000 )
end
end
def fileExit
emit $qApp.quit if confirmExit
end
def closeEvent(e)
if confirmExit
e.accept
else
e.ignore
end
end
def confirmExit
ret = 0
return true if @executedLines.empty?
ret = TQt::MessageBox::warning(
self,
"Warning" ,
"A session is opened, quit anyway ?",
TQt::MessageBox::Yes,
TQt::MessageBox::No)
return ret != TQt::MessageBox::No
end
def emptySession
empty = @executedLines.empty?
statusBar.message("Session is empty...", 3000) if empty
empty
end
def runSelection
emit selection(@sessionLog.selectedText())
end
def helpExample
emit fileNeedsEval("__DATA__")
end
end
class QtShell < TQt::MainWindow
slots 'evalInput()', 'evalFile(TQString)', 'evalSelection(TQString)'
attr_accessor :shellWindow
@@binding = binding
def bind
@@binding
end
def initialize(*k)
super(*k)
@shellWindow = QtShellControl.new(nil, "shellWindow")
self.resize(350,350)
self.move(Point.new(10,10))
@shellWindow.move(Point.new(300,200))
self.show
@shellWindow.show
connect(@shellWindow.comboBox.lineEdit, TQ_SIGNAL('returnPressed()'), self, TQ_SLOT('evalInput()'))
@prompt = '<b><font color="blue">$&gt;</font></b>'
self.setCaption("MainWindow - this")
@shellWindow.sessionLog.setText("Ready.<br>")
connect(@shellWindow, TQ_SIGNAL('fileNeedsEval(TQString)'), self, TQ_SLOT('evalFile(TQString)'))
connect(@shellWindow, TQ_SIGNAL('selection(TQString)'), self, TQ_SLOT('evalSelection(TQString)'))
end
def logAppend(str)
tmp = @shellWindow.sessionLog.text << str
@shellWindow.sessionLog.setText tmp
end
def evalInput
evalOneLine @shellWindow.comboBox.currentText
end
=begin
sub TIEHANDLE { my ( $classnm, $widg, $color) = @_;
my $h = { widg => $widg, color => $color};
bless $h, $classnm;
}
sub PRINT {
my $me = shift;
my $color = $me->{color};
my $printed = join $/, @_;
$printed =~ s/</&lt;/gs;
$printed =~ s/>/&gt;/gs;
$printed =~ s/\n/<br>/gs;
$me->{widg}->setText( $me->{widg}->text . "<font color=\"$color\">$printed</font>" );
}
#tie *STDOUT, 'TQt::TextHandle', $shw->sessionLog, 'black';
#tie *STDERR, 'TQt::TextHandle', $shw->sessionLog, 'red';
=end
def evalOneLine(line)
prot = ln = line
prot.gsub('<', '&lt;') # /gs ???
prot.gsub('>', '&gt;') # /gs ???
logAppend( "#{@prompt}#{prot}" )
ostdout, ostderr = $stdout, $stderr
strio = StringIO.new
$stdout, $stderr = strio, strio
begin
if line =~ /^\$(.*)$/
eval $1, bind
else
eval line
end
rescue StandardError, ScriptError => e
prot = e.to_str
prot.gsub(/</, '&lt;') # /gs ???
prot.gsub(/>/, '&gt;') # /gs ???
c = @shellWindow.sessionLog.color
prot.gsub(/\n/, '<br>') # /gs ???
logAppend '<font color="red">' << prot << '</font><br>'
shellWindow.sessionLog.setColor c
end
logAppend '<font color="blue">' << strio.string << '</font><br>'
@shellWindow.executedLines << line
@shellWindow.comboBox.clearEdit
@shellWindow.comboBox.setFocus
$stdout, $stderr = ostdout, ostderr
@shellWindow.sessionLog.scrollToBottom
end
def evalFile(fname)
if fname == "__DATA__"
file = StringIO.new
file.string = $example
else
file = File.open(fname, "r")
if file.nil?
# TODO use $! -> error message!
TQt::MessageBox::warning(
self,
"Error" ,
"Couldn't open @{$fn}: $!",
TQt::MessageBox::Ok,
TQt::MessageBox::NoButton)
return
end
indata = file
end
file.each_line {
|line|
evalOneLine(line)
}
file.close
end
def evalSelection(selection)
evalOneLine(selection.sub(/.*span>/, "")) unless selection.nil?
end
end
app = TQt::Application.new(ARGV)
w = QtShell.new(nil, "mainWindow")
app.setMainWidget(w.shellWindow)
app.exec
BEGIN {
$example = <<EXAMPLE
$ attr_accessor :datetime, :button, :textedit, :sample, :vbox
statusBar.message("Hello World !")
@vbox = VBox.new(self)
@datetime = DateTimeEdit.new(vbox)
@textedit = TextEdit.new(vbox)
@button = PushButton.new("Hello World!", vbox)
self.setCentralWidget(vbox)
self.resize(220,240)
@vbox.show
@sample = TQt::PopupMenu.new(self)
$ slots 'there()'
@sample.insertItem("&There", self, TQ_SLOT('there()'))
self.menuBar.insertItem("&Here", sample)
$ def there; statusBar.message("There...", 2000); end
EXAMPLE
}