diff options
Diffstat (limited to 'qtruby/bin/rbqtsh')
-rwxr-xr-x | qtruby/bin/rbqtsh | 627 |
1 files changed, 627 insertions, 0 deletions
diff --git a/qtruby/bin/rbqtsh b/qtruby/bin/rbqtsh new file mode 100755 index 00000000..b9d8ee9e --- /dev/null +++ b/qtruby/bin/rbqtsh @@ -0,0 +1,627 @@ +#!/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 "rbkdesh" + 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 < Qt::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(QString)', 'selection(QString)' + + def initialize(*k) + super(*k) + image0 = Qt::Pixmap.new($image0_data) + image1 = Qt::Pixmap.new($image1_data) + image2 = Qt::Pixmap.new($image2_data) + image3 = Qt::Pixmap.new($image3_data) + box = VBox.new(self) + @sessionLog = TextEdit.new(box, "sessionLog") + @sessionLog.setTextFormat(Qt::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 = Qt::Action.new(self, "fileOpenAction") + @fileOpenAction.setIconSet(Qt::IconSet.new(image1)) + @fileOpenAction.setText(trUtf8("Open")) + @fileOpenAction.setMenuText(trUtf8("&Open...")) + @fileOpenAction.setAccel(KeySequence.new(trUtf8("Ctrl+O"))) + @fileSaveAction = Qt::Action.new(self, "fileSaveAction") + @fileSaveAction.setIconSet(Qt::IconSet.new(image2)) + @fileSaveAction.setText(trUtf8("Save")) + @fileSaveAction.setMenuText(trUtf8("&Save")) + @fileSaveAction.setAccel(KeySequence.new(trUtf8("Ctrl+S"))) + @fileSaveAsAction = Qt::Action.new(self, "fileSaveAsAction") + @fileSaveAsAction.setText(trUtf8("Save As")) + @fileSaveAsAction.setMenuText(trUtf8("Save &As...")) + @fileSaveAsAction.setAccel(KeySequence.new(trUtf8("Ctrl+A"))) + @filePrintAction = Qt::Action.new(self, "filePrintAction") + @filePrintAction.setIconSet(Qt::IconSet.new(image3)) + @filePrintAction.setText(trUtf8("Print")) + @filePrintAction.setMenuText(trUtf8("&Print...")) + @filePrintAction.setAccel(KeySequence.new(trUtf8("Ctrl+P"))) + @fileExitAction = Qt::Action.new(self, "fileExitAction") + @fileExitAction.setText(trUtf8("Exit")) + @fileExitAction.setMenuText(trUtf8("E&xit")) + @fileExitAction.setAccel(KeySequence.new(trUtf8("Ctrl+E"))) + + @runAction = Qt::Action.new(self, "runAction"); + @runAction.setText(trUtf8("Run Selection")); + @runAction.setMenuText(trUtf8("&Run Selection")); + @runAction.setAccel(KeySequence.new(trUtf8("Ctrl+R"))); + + @helpExampleAction = Qt::Action.new(self, "helpExampleAction"); + @helpExampleAction.setText(trUtf8("Example")); + @helpExampleAction.setMenuText(trUtf8("Examp&le")); + @helpExampleAction.setAccel(KeySequence.new(trUtf8("Ctrl+L"))); + + @toolBar = Qt::ToolBar.new("", self, DockTop) + @toolBar.setLabel(trUtf8("Tools")) + + @fileOpenAction.addTo(toolBar) + @fileSaveAction.addTo(toolBar) + @filePrintAction.addTo(toolBar) + + @menubar= Qt::MenuBar.new(self, "menubar") + + @fileMenu= Qt::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= Qt::PopupMenu.new(self) + @runAction.addTo(@runMenu) + @menubar.insertItem(trUtf8("Run"), @runMenu) + + @menubar.insertSeparator + + @helpMenu= Qt::PopupMenu.new(self) + @helpExampleAction.addTo(helpMenu) + @menubar.insertItem(trUtf8("&Help"), helpMenu) + + connect(@fileOpenAction, SIGNAL('activated()'), self, SLOT('fileOpen()')) + connect(@fileSaveAction, SIGNAL('activated()'), self, SLOT('fileSave()')) + connect(@fileSaveAsAction, SIGNAL('activated()'), self, SLOT('fileSaveAs()')) + connect(@filePrintAction, SIGNAL('activated()'), self, SLOT('filePrint()')) + connect(@fileExitAction, SIGNAL('activated()'), self, SLOT('fileExit()')) + connect(@runAction, SIGNAL('activated()'), self, SLOT('runSelection()')) + connect(@helpExampleAction, SIGNAL('activated()'), self, SLOT('helpExample()')) + + @executedLines = [] + end + + def fileOpen + fname = Qt::FileDialog::getOpenFileName( + ".", + "Rbqtsh Session (*.rbqts)", + self, + "open session", + "Choose a file to open") + return if fname.nil? + emit fileNeedsEval(fname) + end + + def getFileName + @fileName = Qt::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 + Qt::MessageBox::critical( + self, + "Error" , + "Couldn't open #{fname} for writing: unknown", + Qt::MessageBox::Ok, + Qt::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 = Qt::MessageBox::warning( + self, + "Warning" , + "File exists, overwrite ?", + Qt::MessageBox::Yes, + Qt::MessageBox::No ) + else + cond = 0 + end + fileSaveAs(cond) if (cond == 0) and ret == Qt::MessageBox::No + save(fname) + end + + def filePrint() + margin = 10 + pageNo = 1 + emptySession() and return + printer = Qt::Printer.new() + if printer.setup(self) + statusBar().message( "Printing..." ) + p = Qt::Painter.new() + if ! p.begin( printer ) + statusBar().message( "An error occured..." ) + return + end + + p.setFont( sessionLog.font() ) + yPos = 0 + fm = p.fontMetrics + metrics = Qt::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 = Qt::MessageBox::warning( + self, + "Warning" , + "A session is opened, quit anyway ?", + Qt::MessageBox::Yes, + Qt::MessageBox::No) + return ret != Qt::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 < Qt::MainWindow + slots 'evalInput()', 'evalFile(QString)', 'evalSelection(QString)' + 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, SIGNAL('returnPressed()'), self, SLOT('evalInput()')) + + @prompt = '<b><font color="blue">$></font></b>' + self.setCaption("MainWindow - this") + @shellWindow.sessionLog.setText("Ready.<br>") + connect(@shellWindow, SIGNAL('fileNeedsEval(QString)'), self, SLOT('evalFile(QString)')) + connect(@shellWindow, SIGNAL('selection(QString)'), self, SLOT('evalSelection(QString)')) +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/</</gs; + $printed =~ s/>/>/gs; + $printed =~ s/\n/<br>/gs; + $me->{widg}->setText( $me->{widg}->text . "<font color=\"$color\">$printed</font>" ); +} + +#tie *STDOUT, 'Qt::TextHandle', $shw->sessionLog, 'black'; +#tie *STDERR, 'Qt::TextHandle', $shw->sessionLog, 'red'; + +=end + +def evalOneLine(line) + prot = ln = line + prot.gsub('<', '<') # /gs ??? + prot.gsub('>', '>') # /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(/</, '<') # /gs ??? + prot.gsub(/>/, '>') # /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! + Qt::MessageBox::warning( + self, + "Error" , + "Couldn't open @{$fn}: $!", + Qt::MessageBox::Ok, + Qt::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 = Qt::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 = Qt::PopupMenu.new(self) +$ slots 'there()' +@sample.insertItem("&There", self, SLOT('there()')) +self.menuBar.insertItem("&Here", sample) +$ def there; statusBar.message("There...", 2000); end +EXAMPLE +} |