author | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
commit | 15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff) | |
tree | c2fa0399a2c47fda8e2cd0092c73a809d17f68eb /core/apps/embeddedkonsole/konsole.cpp | |
download | opie-15318cad33835e4e2dc620d033e43cd930676cdd.zip opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2 |
Initial revision
Diffstat (limited to 'core/apps/embeddedkonsole/konsole.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | core/apps/embeddedkonsole/konsole.cpp | 512 |
1 files changed, 512 insertions, 0 deletions
diff --git a/core/apps/embeddedkonsole/konsole.cpp b/core/apps/embeddedkonsole/konsole.cpp new file mode 100644 index 0000000..7253baf --- a/dev/null +++ b/core/apps/embeddedkonsole/konsole.cpp | |||
@@ -0,0 +1,512 @@ | |||
1 | /* ---------------------------------------------------------------------- */ | ||
2 | /* */ | ||
3 | /* [main.C] Konsole */ | ||
4 | /* */ | ||
5 | /* ---------------------------------------------------------------------- */ | ||
6 | /* */ | ||
7 | /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ | ||
8 | /* */ | ||
9 | /* This file is part of Konsole, an X terminal. */ | ||
10 | /* */ | ||
11 | /* The material contained in here more or less directly orginates from */ | ||
12 | /* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */ | ||
13 | /* */ | ||
14 | /* ---------------------------------------------------------------------- */ | ||
15 | /* */ | ||
16 | /* Ported Konsole to Qt/Embedded */ | ||
17 | /* */ | ||
18 | /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ | ||
19 | /* */ | ||
20 | /* -------------------------------------------------------------------------- */ | ||
21 | |||
22 | #include <qpe/resource.h> | ||
23 | |||
24 | #include <qdir.h> | ||
25 | #include <qevent.h> | ||
26 | #include <qdragobject.h> | ||
27 | #include <qobjectlist.h> | ||
28 | #include <qtoolbutton.h> | ||
29 | #include <qpe/qpetoolbar.h> | ||
30 | #include <qpushbutton.h> | ||
31 | #include <qfontdialog.h> | ||
32 | #include <qglobal.h> | ||
33 | #include <qpainter.h> | ||
34 | #include <qpe/qpemenubar.h> | ||
35 | #include <qmessagebox.h> | ||
36 | #include <qaction.h> | ||
37 | #include <qapplication.h> | ||
38 | #include <qfontmetrics.h> | ||
39 | #include <qcombobox.h> | ||
40 | #include <qevent.h> | ||
41 | #include <qtabwidget.h> | ||
42 | #include <qtabbar.h> | ||
43 | #include <qpe/config.h> | ||
44 | |||
45 | #include <sys/wait.h> | ||
46 | #include <stdio.h> | ||
47 | #include <stdlib.h> | ||
48 | #include <assert.h> | ||
49 | |||
50 | #include "konsole.h" | ||
51 | #include "keytrans.h" | ||
52 | |||
53 | class EKNumTabBar : public QTabBar { | ||
54 | public: | ||
55 | void numberTabs() | ||
56 | { | ||
57 | // Yes, it really is this messy. QTabWidget needs functions | ||
58 | // that provide acces to tabs in a sequential way. | ||
59 | int m=INT_MIN; | ||
60 | for (int i=0; i<count(); i++) { | ||
61 | QTab* left=0; | ||
62 | QListIterator<QTab> it(*tabList()); | ||
63 | int x=INT_MAX; | ||
64 | for( QTab* t; (t=it.current()); ++it ) { | ||
65 | int tx = t->rect().x(); | ||
66 | if ( tx<x && tx>m ) { | ||
67 | x = tx; | ||
68 | left = t; | ||
69 | } | ||
70 | } | ||
71 | if ( left ) { | ||
72 | left->setText(QString::number(i+1)); | ||
73 | m = left->rect().x(); | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | }; | ||
78 | |||
79 | class EKNumTabWidget : public QTabWidget { | ||
80 | public: | ||
81 | EKNumTabWidget(QWidget* parent) : QTabWidget(parent) | ||
82 | { | ||
83 | } | ||
84 | |||
85 | void addTab(QWidget* w) | ||
86 | { | ||
87 | QTab* t = new QTab(QString::number(tabBar()->count()+1)); | ||
88 | QTabWidget::addTab(w,t); | ||
89 | } | ||
90 | |||
91 | void removeTab(QWidget* w) | ||
92 | { | ||
93 | removePage(w); | ||
94 | ((EKNumTabBar*)tabBar())->numberTabs(); | ||
95 | } | ||
96 | }; | ||
97 | |||
98 | // This could be configurable or dynamicly generated from the bash history | ||
99 | // file of the user | ||
100 | static const char *commonCmds[] = | ||
101 | { | ||
102 | "ls ", | ||
103 | //"ls -la ", | ||
104 | "cd ", | ||
105 | "pwd", | ||
106 | //"cat", | ||
107 | //"less ", | ||
108 | //"vi ", | ||
109 | //"man ", | ||
110 | "echo ", | ||
111 | "set ", | ||
112 | //"ps", | ||
113 | "ps aux", | ||
114 | //"tar", | ||
115 | //"tar -zxf", | ||
116 | "grep ", | ||
117 | //"grep -i", | ||
118 | //"mkdir", | ||
119 | "cp ", | ||
120 | "mv ", | ||
121 | "rm ", | ||
122 | "rmdir ", | ||
123 | //"chmod", | ||
124 | //"su", | ||
125 | // "top", | ||
126 | //"find", | ||
127 | //"make", | ||
128 | //"tail", | ||
129 | "cardctl eject", | ||
130 | "ifconfig ", | ||
131 | // "iwconfig eth0 ", | ||
132 | "nc localhost 7777", | ||
133 | "nc localhost 7776", | ||
134 | //"mount /dev/hda1", | ||
135 | |||
136 | /* | ||
137 | "gzip", | ||
138 | "gunzip", | ||
139 | "chgrp", | ||
140 | "chown", | ||
141 | "date", | ||
142 | "dd", | ||
143 | "df", | ||
144 | "dmesg", | ||
145 | "fuser", | ||
146 | "hostname", | ||
147 | "kill", | ||
148 | "killall", | ||
149 | "ln", | ||
150 | "ping", | ||
151 | "mount", | ||
152 | "more", | ||
153 | "sort", | ||
154 | "touch", | ||
155 | "umount", | ||
156 | "mknod", | ||
157 | "netstat", | ||
158 | */ | ||
159 | |||
160 | "exit", | ||
161 | NULL | ||
162 | }; | ||
163 | |||
164 | |||
165 | Konsole::Konsole(QWidget* parent, const char* name, WFlags fl) : | ||
166 | QMainWindow(parent, name, fl) | ||
167 | { | ||
168 | QStrList args; | ||
169 | init("/bin/sh",args); | ||
170 | } | ||
171 | |||
172 | Konsole::Konsole(const char* name, const char* _pgm, QStrList & _args, int) | ||
173 | : QMainWindow(0, name) | ||
174 | { | ||
175 | init(_pgm,_args); | ||
176 | } | ||
177 | |||
178 | void Konsole::init(const char* _pgm, QStrList & _args) | ||
179 | { | ||
180 | b_scroll = TRUE; // histon; | ||
181 | n_keytab = 0; | ||
182 | n_render = 0; | ||
183 | |||
184 | setCaption( tr("Terminal") ); | ||
185 | setIcon( Resource::loadPixmap( "konsole" ) ); | ||
186 | |||
187 | Config cfg("Konsole"); | ||
188 | cfg.setGroup("Konsole"); | ||
189 | |||
190 | // initialize the list of allowed fonts /////////////////////////////////// | ||
191 | cfont = cfg.readNumEntry("FontID", 1); | ||
192 | QFont f = QFont("Micro", 4, QFont::Normal); | ||
193 | f.setFixedPitch(TRUE); | ||
194 | fonts.append(new VTFont(tr("Micro"), f)); | ||
195 | |||
196 | f = QFont("Fixed", 7, QFont::Normal); | ||
197 | f.setFixedPitch(TRUE); | ||
198 | fonts.append(new VTFont(tr("Small Fixed"), f)); | ||
199 | |||
200 | f = QFont("Fixed", 12, QFont::Normal); | ||
201 | f.setFixedPitch(TRUE); | ||
202 | fonts.append(new VTFont(tr("Medium Fixed"), f)); | ||
203 | |||
204 | // create terminal emulation framework //////////////////////////////////// | ||
205 | nsessions = 0; | ||
206 | tab = new EKNumTabWidget(this); | ||
207 | tab->setTabPosition(QTabWidget::Bottom); | ||
208 | connect(tab, SIGNAL(currentChanged(QWidget*)), this, SLOT(switchSession(QWidget*))); | ||
209 | |||
210 | // create terminal toolbar //////////////////////////////////////////////// | ||
211 | setToolBarsMovable( FALSE ); | ||
212 | QPEToolBar *menuToolBar = new QPEToolBar( this ); | ||
213 | menuToolBar->setHorizontalStretchable( TRUE ); | ||
214 | |||
215 | QPEMenuBar *menuBar = new QPEMenuBar( menuToolBar ); | ||
216 | |||
217 | fontList = new QPopupMenu( this ); | ||
218 | for(uint i = 0; i < fonts.count(); i++) { | ||
219 | VTFont *fnt = fonts.at(i); | ||
220 | fontList->insertItem(fnt->getName(), i); | ||
221 | } | ||
222 | fontChanged(cfont); | ||
223 | |||
224 | connect( fontList, SIGNAL( activated(int) ), this, SLOT( fontChanged(int) )); | ||
225 | |||
226 | menuBar->insertItem( tr("Font"), fontList ); | ||
227 | |||
228 | QPEToolBar *toolbar = new QPEToolBar( this ); | ||
229 | |||
230 | QAction *a; | ||
231 | |||
232 | // Button Commands | ||
233 | a = new QAction( tr("New"), Resource::loadPixmap( "konsole" ), QString::null, 0, this, 0 ); | ||
234 | connect( a, SIGNAL( activated() ), this, SLOT( newSession() ) ); a->addTo( toolbar ); | ||
235 | a = new QAction( tr("Enter"), Resource::loadPixmap( "konsole/enter" ), QString::null, 0, this, 0 ); | ||
236 | connect( a, SIGNAL( activated() ), this, SLOT( hitEnter() ) ); a->addTo( toolbar ); | ||
237 | a = new QAction( tr("Space"), Resource::loadPixmap( "konsole/space" ), QString::null, 0, this, 0 ); | ||
238 | connect( a, SIGNAL( activated() ), this, SLOT( hitSpace() ) ); a->addTo( toolbar ); | ||
239 | a = new QAction( tr("Tab"), Resource::loadPixmap( "konsole/tab" ), QString::null, 0, this, 0 ); | ||
240 | connect( a, SIGNAL( activated() ), this, SLOT( hitTab() ) ); a->addTo( toolbar ); | ||
241 | a = new QAction( tr("Up"), Resource::loadPixmap( "konsole/up" ), QString::null, 0, this, 0 ); | ||
242 | connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar ); | ||
243 | a = new QAction( tr("Down"), Resource::loadPixmap( "konsole/down" ), QString::null, 0, this, 0 ); | ||
244 | connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar ); | ||
245 | a = new QAction( tr("Paste"), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 ); | ||
246 | connect( a, SIGNAL( activated() ), this, SLOT( hitPaste() ) ); a->addTo( toolbar ); | ||
247 | /* | ||
248 | a = new QAction( tr("Up"), Resource::loadPixmap( "up" ), QString::null, 0, this, 0 ); | ||
249 | connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar ); | ||
250 | a = new QAction( tr("Down"), Resource::loadPixmap( "down" ), QString::null, 0, this, 0 ); | ||
251 | connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar ); | ||
252 | */ | ||
253 | |||
254 | QPEToolBar *secondToolBar = new QPEToolBar( this ); | ||
255 | secondToolBar->setHorizontalStretchable( TRUE ); | ||
256 | |||
257 | QComboBox *commonCombo = new QComboBox( secondToolBar ); | ||
258 | // commonCombo->setEditable( TRUE ); | ||
259 | for (int i = 0; commonCmds[i] != NULL; i++) | ||
260 | commonCombo->insertItem( commonCmds[i], i ); | ||
261 | connect( commonCombo, SIGNAL( activated(int) ), this, SLOT( enterCommand(int) )); | ||
262 | |||
263 | // create applications ///////////////////////////////////////////////////// | ||
264 | setCentralWidget(tab); | ||
265 | |||
266 | // load keymaps //////////////////////////////////////////////////////////// | ||
267 | KeyTrans::loadAll(); | ||
268 | for (int i = 0; i < KeyTrans::count(); i++) | ||
269 | { KeyTrans* s = KeyTrans::find(i); | ||
270 | assert( s ); | ||
271 | } | ||
272 | |||
273 | se_pgm = _pgm; | ||
274 | se_args = _args; | ||
275 | |||
276 | // read and apply default values /////////////////////////////////////////// | ||
277 | resize(321, 321); // Dummy. | ||
278 | QSize currentSize = size(); | ||
279 | if (currentSize != size()) | ||
280 | defaultSize = size(); | ||
281 | } | ||
282 | |||
283 | void Konsole::show() | ||
284 | { | ||
285 | if ( !nsessions ) { | ||
286 | newSession(); | ||
287 | } | ||
288 | QMainWindow::show(); | ||
289 | } | ||
290 | |||
291 | void Konsole::initSession(const char*, QStrList &) | ||
292 | { | ||
293 | QMainWindow::show(); | ||
294 | } | ||
295 | |||
296 | Konsole::~Konsole() | ||
297 | { | ||
298 | while (nsessions > 0) { | ||
299 | doneSession(getTe()->currentSession, 0); | ||
300 | } | ||
301 | |||
302 | Config cfg("Konsole"); | ||
303 | cfg.setGroup("Konsole"); | ||
304 | cfg.writeEntry("FontID", cfont); | ||
305 | } | ||
306 | |||
307 | void Konsole::fontChanged(int f) | ||
308 | { | ||
309 | VTFont* font = fonts.at(f); | ||
310 | if (font != 0) { | ||
311 | for(uint i = 0; i < fonts.count(); i++) { | ||
312 | fontList->setItemChecked(i, (i == (uint) f) ? TRUE : FALSE); | ||
313 | } | ||
314 | |||
315 | cfont = f; | ||
316 | |||
317 | TEWidget* te = getTe(); | ||
318 | if (te != 0) { | ||
319 | te->setVTFont(font->getFont()); | ||
320 | } | ||
321 | } | ||
322 | } | ||
323 | |||
324 | void Konsole::enterCommand(int c) | ||
325 | { | ||
326 | TEWidget* te = getTe(); | ||
327 | if (te != 0) { | ||
328 | QString text = commonCmds[c]; | ||
329 | te->emitText(text); | ||
330 | } | ||
331 | } | ||
332 | |||
333 | void Konsole::hitEnter() | ||
334 | { | ||
335 | TEWidget* te = getTe(); | ||
336 | if (te != 0) { | ||
337 | te->emitText(QString("\r")); | ||
338 | } | ||
339 | } | ||
340 | |||
341 | void Konsole::hitSpace() | ||
342 | { | ||
343 | TEWidget* te = getTe(); | ||
344 | if (te != 0) { | ||
345 | te->emitText(QString(" ")); | ||
346 | } | ||
347 | } | ||
348 | |||
349 | void Konsole::hitTab() | ||
350 | { | ||
351 | TEWidget* te = getTe(); | ||
352 | if (te != 0) { | ||
353 | te->emitText(QString("\t")); | ||
354 | } | ||
355 | } | ||
356 | |||
357 | void Konsole::hitPaste() | ||
358 | { | ||
359 | TEWidget* te = getTe(); | ||
360 | if (te != 0) { | ||
361 | te->pasteClipboard(); | ||
362 | } | ||
363 | } | ||
364 | |||
365 | void Konsole::hitUp() | ||
366 | { | ||
367 | TEWidget* te = getTe(); | ||
368 | if (te != 0) { | ||
369 | QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Up, 0, 0); | ||
370 | QApplication::sendEvent( te, &ke ); | ||
371 | } | ||
372 | } | ||
373 | |||
374 | void Konsole::hitDown() | ||
375 | { | ||
376 | TEWidget* te = getTe(); | ||
377 | if (te != 0) { | ||
378 | QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Down, 0, 0); | ||
379 | QApplication::sendEvent( te, &ke ); | ||
380 | } | ||
381 | } | ||
382 | |||
383 | /** | ||
384 | This function calculates the size of the external widget | ||
385 | needed for the internal widget to be | ||
386 | */ | ||
387 | QSize Konsole::calcSize(int columns, int lines) { | ||
388 | TEWidget* te = getTe(); | ||
389 | if (te != 0) { | ||
390 | QSize size = te->calcSize(columns, lines); | ||
391 | return size; | ||
392 | } else { | ||
393 | QSize size; | ||
394 | return size; | ||
395 | } | ||
396 | } | ||
397 | |||
398 | /** | ||
399 | sets application window to a size based on columns X lines of the te | ||
400 | guest widget. Call with (0,0) for setting default size. | ||
401 | */ | ||
402 | |||
403 | void Konsole::setColLin(int columns, int lines) | ||
404 | { | ||
405 | if ((columns==0) || (lines==0)) | ||
406 | { | ||
407 | if (defaultSize.isEmpty()) // not in config file : set default value | ||
408 | { | ||
409 | defaultSize = calcSize(80,24); | ||
410 | // notifySize(24,80); // set menu items (strange arg order !) | ||
411 | } | ||
412 | resize(defaultSize); | ||
413 | } else { | ||
414 | resize(calcSize(columns, lines)); | ||
415 | // notifySize(lines,columns); // set menu items (strange arg order !) | ||
416 | } | ||
417 | } | ||
418 | |||
419 | /* | ||
420 | void Konsole::setFont(int fontno) | ||
421 | { | ||
422 | QFont f; | ||
423 | if (fontno == 0) | ||
424 | f = defaultFont = QFont( "Helvetica", 12 ); | ||
425 | else | ||
426 | if (fonts[fontno][0] == '-') | ||
427 | f.setRawName( fonts[fontno] ); | ||
428 | else | ||
429 | { | ||
430 | f.setFamily(fonts[fontno]); | ||
431 | f.setRawMode( TRUE ); | ||
432 | } | ||
433 | if ( !f.exactMatch() && fontno != 0) | ||
434 | { | ||
435 | QString msg = i18n("Font `%1' not found.\nCheck README.linux.console for help.").arg(fonts[fontno]); | ||
436 | QMessageBox(this, msg); | ||
437 | return; | ||
438 | } | ||
439 | if (se) se->setFontNo(fontno); | ||
440 | te->setVTFont(f); | ||
441 | n_font = fontno; | ||
442 | } | ||
443 | */ | ||
444 | |||
445 | // --| color selection |------------------------------------------------------- | ||
446 | |||
447 | void Konsole::changeColumns(int columns) | ||
448 | { | ||
449 | TEWidget* te = getTe(); | ||
450 | if (te != 0) { | ||
451 | setColLin(columns,te->Lines()); | ||
452 | te->update(); | ||
453 | } | ||
454 | } | ||
455 | |||
456 | //FIXME: If a child dies during session swap, | ||
457 | // this routine might be called before | ||
458 | // session swap is completed. | ||
459 | |||
460 | void Konsole::doneSession(TESession*, int ) | ||
461 | { | ||
462 | TEWidget *te = getTe(); | ||
463 | if (te != 0) { | ||
464 | te->currentSession->setConnect(FALSE); | ||
465 | tab->removeTab(te); | ||
466 | delete te->currentSession; | ||
467 | delete te; | ||
468 | nsessions--; | ||
469 | } | ||
470 | |||
471 | if (nsessions == 0) { | ||
472 | close(); | ||
473 | } | ||
474 | } | ||
475 | |||
476 | |||
477 | void Konsole::newSession() { | ||
478 | TEWidget* te = new TEWidget(tab); | ||
479 | te->setBackgroundMode(PaletteBase); | ||
480 | te->setVTFont(fonts.at(cfont)->getFont()); | ||
481 | tab->addTab(te); | ||
482 | TESession* se = new TESession(this, te, se_pgm, se_args, "xterm"); | ||
483 | te->currentSession = se; | ||
484 | connect( se, SIGNAL(done(TESession*,int)), this, SLOT(doneSession(TESession*,int)) ); | ||
485 | se->run(); | ||
486 | se->setConnect(TRUE); | ||
487 | se->setHistory(b_scroll); | ||
488 | tab->setCurrentPage(nsessions); | ||
489 | nsessions++; | ||
490 | } | ||
491 | |||
492 | TEWidget* Konsole::getTe() { | ||
493 | if (nsessions) { | ||
494 | return (TEWidget *) tab->currentPage(); | ||
495 | } else { | ||
496 | return 0; | ||
497 | } | ||
498 | } | ||
499 | |||
500 | void Konsole::switchSession(QWidget* w) { | ||
501 | TEWidget* te = (TEWidget *) w; | ||
502 | |||
503 | QFont teFnt = te->getVTFont(); | ||
504 | for(uint i = 0; i < fonts.count(); i++) { | ||
505 | VTFont *fnt = fonts.at(i); | ||
506 | bool cf = fnt->getFont() == teFnt; | ||
507 | fontList->setItemChecked(i, cf); | ||
508 | if (cf) { | ||
509 | cfont = i; | ||
510 | } | ||
511 | } | ||
512 | } | ||