1 | /* Copyright (C) 2008 e_k (e_k@users.sourceforge.net) |
2 | |
3 | This library is free software; you can redistribute it and/or |
4 | modify it under the terms of the GNU Library General Public |
5 | License as published by the Free Software Foundation; either |
6 | version 2 of the License, or (at your option) any later version. |
7 | |
8 | This library is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
11 | Library General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU Library General Public License |
14 | along with this library; see the file COPYING.LIB. If not, write to |
15 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
16 | Boston, MA 02110-1301, USA. |
17 | */ |
18 | |
19 | #include <QLayout> |
20 | #include <QBoxLayout> |
21 | #include <QtDebug> |
22 | #include <QDir> |
23 | #include <QMessageBox> |
24 | |
25 | #include "ColorTables.h" |
26 | #include "Session.h" |
27 | #include "Screen.h" |
28 | #include "ScreenWindow.h" |
29 | #include "Emulation.h" |
30 | #include "TerminalDisplay.h" |
31 | #include "KeyboardTranslator.h" |
32 | #include "ColorScheme.h" |
33 | #include "SearchBar.h" |
34 | #include "qtermwidget.h" |
35 | |
36 | |
37 | #define STEP_ZOOM 1 |
38 | |
39 | using namespace Konsole; |
40 | |
41 | void *createTermWidget(int startnow, void *parent) |
42 | { |
43 | return (void*) new QTermWidget(startnow, (QWidget*)parent); |
44 | } |
45 | |
46 | struct TermWidgetImpl { |
47 | TermWidgetImpl(QWidget* parent = 0); |
48 | |
49 | TerminalDisplay *m_terminalDisplay; |
50 | Session *m_session; |
51 | |
52 | Session* createSession(QWidget* parent); |
53 | TerminalDisplay* createTerminalDisplay(Session *session, QWidget* parent); |
54 | }; |
55 | |
56 | TermWidgetImpl::TermWidgetImpl(QWidget* parent) |
57 | { |
58 | this->m_session = createSession(parent); |
59 | this->m_terminalDisplay = createTerminalDisplay(this->m_session, parent); |
60 | } |
61 | |
62 | |
63 | Session *TermWidgetImpl::createSession(QWidget* parent) |
64 | { |
65 | Session *session = new Session(parent); |
66 | |
67 | session->setTitle(Session::NameRole, QLatin1String("QTermWidget" )); |
68 | |
69 | /* Thats a freaking bad idea!!!! |
70 | * /bin/bash is not there on every system |
71 | * better set it to the current $SHELL |
72 | * Maybe you can also make a list available and then let the widget-owner decide what to use. |
73 | * By setting it to $SHELL right away we actually make the first filecheck obsolete. |
74 | * But as iam not sure if you want to do anything else ill just let both checks in and set this to $SHELL anyway. |
75 | */ |
76 | //session->setProgram("/bin/bash"); |
77 | |
78 | session->setProgram(QString::fromLocal8Bit(qgetenv("SHELL" ))); |
79 | |
80 | |
81 | |
82 | QStringList args = QStringList(QString()); |
83 | session->setArguments(args); |
84 | session->setAutoClose(true); |
85 | |
86 | session->setCodec(QTextCodec::codecForName("UTF-8" )); |
87 | |
88 | session->setFlowControlEnabled(true); |
89 | session->setHistoryType(HistoryTypeBuffer(1000)); |
90 | |
91 | session->setDarkBackground(true); |
92 | |
93 | session->setKeyBindings(QString()); |
94 | return session; |
95 | } |
96 | |
97 | TerminalDisplay *TermWidgetImpl::createTerminalDisplay(Session *session, QWidget* parent) |
98 | { |
99 | // TerminalDisplay* display = new TerminalDisplay(this); |
100 | TerminalDisplay* display = new TerminalDisplay(parent); |
101 | |
102 | display->setBellMode(TerminalDisplay::NotifyBell); |
103 | display->setTerminalSizeHint(true); |
104 | display->setTripleClickMode(TerminalDisplay::SelectWholeLine); |
105 | display->setTerminalSizeStartup(true); |
106 | |
107 | display->setRandomSeed(session->sessionId() * 31); |
108 | |
109 | return display; |
110 | } |
111 | |
112 | |
113 | QTermWidget::QTermWidget(int startnow, QWidget *parent) |
114 | : QWidget(parent) |
115 | { |
116 | init(startnow); |
117 | } |
118 | |
119 | QTermWidget::QTermWidget(QWidget *parent) |
120 | : QWidget(parent) |
121 | { |
122 | init(1); |
123 | } |
124 | |
125 | void QTermWidget::selectionChanged(bool textSelected) |
126 | { |
127 | emit copyAvailable(textSelected); |
128 | } |
129 | |
130 | void QTermWidget::find() |
131 | { |
132 | search(true, false); |
133 | } |
134 | |
135 | void QTermWidget::findNext() |
136 | { |
137 | search(true, true); |
138 | } |
139 | |
140 | void QTermWidget::findPrevious() |
141 | { |
142 | search(false, false); |
143 | } |
144 | |
145 | void QTermWidget::search(bool forwards, bool next) |
146 | { |
147 | int startColumn, startLine; |
148 | |
149 | if (next) // search from just after current selection |
150 | { |
151 | m_impl->m_terminalDisplay->screenWindow()->screen()->getSelectionEnd(startColumn, startLine); |
152 | startColumn++; |
153 | } |
154 | else // search from start of current selection |
155 | { |
156 | m_impl->m_terminalDisplay->screenWindow()->screen()->getSelectionStart(startColumn, startLine); |
157 | } |
158 | |
159 | qDebug() << "current selection starts at: " << startColumn << startLine; |
160 | qDebug() << "current cursor position: " << m_impl->m_terminalDisplay->screenWindow()->cursorPosition(); |
161 | |
162 | QRegExp regExp(m_searchBar->searchText()); |
163 | regExp.setPatternSyntax(m_searchBar->useRegularExpression() ? QRegExp::RegExp : QRegExp::FixedString); |
164 | regExp.setCaseSensitivity(m_searchBar->matchCase() ? Qt::CaseSensitive : Qt::CaseInsensitive); |
165 | |
166 | HistorySearch *historySearch = |
167 | new HistorySearch(m_impl->m_session->emulation(), regExp, forwards, startColumn, startLine, this); |
168 | connect(historySearch, SIGNAL(matchFound(int, int, int, int)), this, SLOT(matchFound(int, int, int, int))); |
169 | connect(historySearch, SIGNAL(noMatchFound()), this, SLOT(noMatchFound())); |
170 | connect(historySearch, SIGNAL(noMatchFound()), m_searchBar, SLOT(noMatchFound())); |
171 | historySearch->search(); |
172 | } |
173 | |
174 | |
175 | void QTermWidget::matchFound(int startColumn, int startLine, int endColumn, int endLine) |
176 | { |
177 | ScreenWindow* sw = m_impl->m_terminalDisplay->screenWindow(); |
178 | qDebug() << "Scroll to" << startLine; |
179 | sw->scrollTo(startLine); |
180 | sw->setTrackOutput(false); |
181 | sw->notifyOutputChanged(); |
182 | sw->setSelectionStart(startColumn, startLine - sw->currentLine(), false); |
183 | sw->setSelectionEnd(endColumn, endLine - sw->currentLine()); |
184 | } |
185 | |
186 | void QTermWidget::noMatchFound() |
187 | { |
188 | m_impl->m_terminalDisplay->screenWindow()->clearSelection(); |
189 | } |
190 | |
191 | int QTermWidget::getShellPID() |
192 | { |
193 | return m_impl->m_session->processId(); |
194 | } |
195 | |
196 | void QTermWidget::changeDir(const QString & dir) |
197 | { |
198 | /* |
199 | this is a very hackish way of trying to determine if the shell is in |
200 | the foreground before attempting to change the directory. It may not |
201 | be portable to anything other than Linux. |
202 | */ |
203 | QString strCmd; |
204 | strCmd.setNum(getShellPID()); |
205 | strCmd.prepend(QLatin1String("ps -j " )); |
206 | strCmd.append(QLatin1String(" | tail -1 | awk '{ print $5 }' | grep -q \\+" )); |
207 | int retval = system(strCmd.toStdString().c_str()); |
208 | |
209 | if (!retval) { |
210 | QString cmd = QLatin1String("cd " ) + dir + QLatin1Char('\n'); |
211 | sendText(cmd); |
212 | } |
213 | } |
214 | |
215 | QSize QTermWidget::sizeHint() const |
216 | { |
217 | QSize size = m_impl->m_terminalDisplay->sizeHint(); |
218 | size.rheight() = 150; |
219 | return size; |
220 | } |
221 | |
222 | void QTermWidget::setTerminalSizeHint(bool on) |
223 | { |
224 | m_impl->m_terminalDisplay->setTerminalSizeHint(on); |
225 | } |
226 | |
227 | bool QTermWidget::terminalSizeHint() |
228 | { |
229 | return m_impl->m_terminalDisplay->terminalSizeHint(); |
230 | } |
231 | |
232 | void QTermWidget::startShellProgram() |
233 | { |
234 | if ( m_impl->m_session->isRunning() ) { |
235 | return; |
236 | } |
237 | |
238 | m_impl->m_session->run(); |
239 | } |
240 | |
241 | void QTermWidget::startTerminalTeletype() |
242 | { |
243 | if ( m_impl->m_session->isRunning() ) { |
244 | return; |
245 | } |
246 | |
247 | m_impl->m_session->runEmptyPTY(); |
248 | // redirect data from TTY to external recipient |
249 | connect( m_impl->m_session->emulation(), SIGNAL(sendData(const char *,int)), |
250 | this, SIGNAL(sendData(const char *,int)) ); |
251 | } |
252 | |
253 | void QTermWidget::init(int startnow) |
254 | { |
255 | m_layout = new QVBoxLayout(); |
256 | m_layout->setMargin(0); |
257 | setLayout(m_layout); |
258 | |
259 | // translations |
260 | // First check $XDG_DATA_DIRS. This follows the implementation in libqtxdg |
261 | QString d = QFile::decodeName(qgetenv("XDG_DATA_DIRS" )); |
262 | QStringList dirs = d.split(QLatin1Char(':'), QString::SkipEmptyParts); |
263 | if (dirs.isEmpty()) { |
264 | dirs.append(QString::fromLatin1("/usr/local/share" )); |
265 | dirs.append(QString::fromLatin1("/usr/share" )); |
266 | } |
267 | dirs.append(QFile::decodeName(TRANSLATIONS_DIR)); |
268 | |
269 | m_translator = new QTranslator(this); |
270 | |
271 | for (const QString& dir : dirs) { |
272 | qDebug() << "Trying to load translation file from dir" << dir; |
273 | if (m_translator->load(QLocale::system(), QLatin1String("qtermwidget" ), QLatin1String(QLatin1String("_" )), dir)) { |
274 | qApp->installTranslator(m_translator); |
275 | qDebug() << "Translations found in" << dir; |
276 | break; |
277 | } |
278 | } |
279 | |
280 | m_impl = new TermWidgetImpl(this); |
281 | m_layout->addWidget(m_impl->m_terminalDisplay); |
282 | |
283 | connect(m_impl->m_session, SIGNAL(bellRequest(QString)), m_impl->m_terminalDisplay, SLOT(bell(QString))); |
284 | connect(m_impl->m_terminalDisplay, SIGNAL(notifyBell(QString)), this, SIGNAL(bell(QString))); |
285 | |
286 | connect(m_impl->m_session, SIGNAL(activity()), this, SIGNAL(activity())); |
287 | connect(m_impl->m_session, SIGNAL(silence()), this, SIGNAL(silence())); |
288 | connect(m_impl->m_session, &Session::profileChangeCommandReceived, this, &QTermWidget::profileChanged); |
289 | connect(m_impl->m_session, &Session::receivedData, this, &QTermWidget::receivedData); |
290 | |
291 | // That's OK, FilterChain's dtor takes care of UrlFilter. |
292 | UrlFilter *urlFilter = new UrlFilter(); |
293 | connect(urlFilter, &UrlFilter::activated, this, &QTermWidget::urlActivated); |
294 | m_impl->m_terminalDisplay->filterChain()->addFilter(urlFilter); |
295 | |
296 | m_searchBar = new SearchBar(this); |
297 | m_searchBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum); |
298 | connect(m_searchBar, SIGNAL(searchCriteriaChanged()), this, SLOT(find())); |
299 | connect(m_searchBar, SIGNAL(findNext()), this, SLOT(findNext())); |
300 | connect(m_searchBar, SIGNAL(findPrevious()), this, SLOT(findPrevious())); |
301 | m_layout->addWidget(m_searchBar); |
302 | m_searchBar->hide(); |
303 | |
304 | if (startnow && m_impl->m_session) { |
305 | m_impl->m_session->run(); |
306 | } |
307 | |
308 | this->setFocus( Qt::OtherFocusReason ); |
309 | this->setFocusPolicy( Qt::WheelFocus ); |
310 | m_impl->m_terminalDisplay->resize(this->size()); |
311 | |
312 | this->setFocusProxy(m_impl->m_terminalDisplay); |
313 | connect(m_impl->m_terminalDisplay, SIGNAL(copyAvailable(bool)), |
314 | this, SLOT(selectionChanged(bool))); |
315 | connect(m_impl->m_terminalDisplay, SIGNAL(termGetFocus()), |
316 | this, SIGNAL(termGetFocus())); |
317 | connect(m_impl->m_terminalDisplay, SIGNAL(termLostFocus()), |
318 | this, SIGNAL(termLostFocus())); |
319 | connect(m_impl->m_terminalDisplay, SIGNAL(keyPressedSignal(QKeyEvent *)), |
320 | this, SIGNAL(termKeyPressed(QKeyEvent *))); |
321 | // m_impl->m_terminalDisplay->setSize(80, 40); |
322 | |
323 | QFont font = QApplication::font(); |
324 | font.setFamily(QLatin1String("Monospace" )); |
325 | font.setPointSize(10); |
326 | font.setStyleHint(QFont::TypeWriter); |
327 | setTerminalFont(font); |
328 | m_searchBar->setFont(font); |
329 | |
330 | setScrollBarPosition(NoScrollBar); |
331 | setKeyboardCursorShape(Emulation::KeyboardCursorShape::BlockCursor); |
332 | |
333 | m_impl->m_session->addView(m_impl->m_terminalDisplay); |
334 | |
335 | connect(m_impl->m_session, SIGNAL(resizeRequest(QSize)), this, SLOT(setSize(QSize))); |
336 | connect(m_impl->m_session, SIGNAL(finished()), this, SLOT(sessionFinished())); |
337 | connect(m_impl->m_session, &Session::titleChanged, this, &QTermWidget::titleChanged); |
338 | connect(m_impl->m_session, &Session::cursorChanged, this, &QTermWidget::cursorChanged); |
339 | } |
340 | |
341 | |
342 | QTermWidget::~QTermWidget() |
343 | { |
344 | delete m_impl; |
345 | emit destroyed(); |
346 | } |
347 | |
348 | |
349 | void QTermWidget::setTerminalFont(const QFont &font) |
350 | { |
351 | m_impl->m_terminalDisplay->setVTFont(font); |
352 | } |
353 | |
354 | QFont QTermWidget::getTerminalFont() |
355 | { |
356 | return m_impl->m_terminalDisplay->getVTFont(); |
357 | } |
358 | |
359 | void QTermWidget::setTerminalOpacity(qreal level) |
360 | { |
361 | m_impl->m_terminalDisplay->setOpacity(level); |
362 | } |
363 | |
364 | void QTermWidget::setTerminalBackgroundImage(QString backgroundImage) |
365 | { |
366 | m_impl->m_terminalDisplay->setBackgroundImage(backgroundImage); |
367 | } |
368 | |
369 | void QTermWidget::setShellProgram(const QString &progname) |
370 | { |
371 | if (!m_impl->m_session) |
372 | return; |
373 | m_impl->m_session->setProgram(progname); |
374 | } |
375 | |
376 | void QTermWidget::setWorkingDirectory(const QString& dir) |
377 | { |
378 | if (!m_impl->m_session) |
379 | return; |
380 | m_impl->m_session->setInitialWorkingDirectory(dir); |
381 | } |
382 | |
383 | QString QTermWidget::workingDirectory() |
384 | { |
385 | if (!m_impl->m_session) |
386 | return QString(); |
387 | |
388 | #ifdef Q_OS_LINUX |
389 | // Christian Surlykke: On linux we could look at /proc/<pid>/cwd which should be a link to current |
390 | // working directory (<pid>: process id of the shell). I don't know about BSD. |
391 | // Maybe we could just offer it when running linux, for a start. |
392 | QDir d(QString::fromLatin1("/proc/%1/cwd" ).arg(getShellPID())); |
393 | if (!d.exists()) |
394 | { |
395 | qDebug() << "Cannot find" << d.dirName(); |
396 | goto fallback; |
397 | } |
398 | return d.canonicalPath(); |
399 | #endif |
400 | |
401 | fallback: |
402 | // fallback, initial WD |
403 | return m_impl->m_session->initialWorkingDirectory(); |
404 | } |
405 | |
406 | void QTermWidget::setArgs(const QStringList &args) |
407 | { |
408 | if (!m_impl->m_session) |
409 | return; |
410 | m_impl->m_session->setArguments(args); |
411 | } |
412 | |
413 | void QTermWidget::setTextCodec(QTextCodec *codec) |
414 | { |
415 | if (!m_impl->m_session) |
416 | return; |
417 | m_impl->m_session->setCodec(codec); |
418 | } |
419 | |
420 | void QTermWidget::setColorScheme(const QString& origName) |
421 | { |
422 | const ColorScheme *cs = 0; |
423 | |
424 | const bool isFile = QFile::exists(origName); |
425 | const QString& name = isFile ? |
426 | QFileInfo(origName).baseName() : |
427 | origName; |
428 | |
429 | // avoid legacy (int) solution |
430 | if (!availableColorSchemes().contains(name)) |
431 | { |
432 | if (isFile) |
433 | { |
434 | if (ColorSchemeManager::instance()->loadCustomColorScheme(origName)) |
435 | cs = ColorSchemeManager::instance()->findColorScheme(name); |
436 | else |
437 | qWarning () << Q_FUNC_INFO |
438 | << "cannot load color scheme from" |
439 | << origName; |
440 | } |
441 | |
442 | if (!cs) |
443 | cs = ColorSchemeManager::instance()->defaultColorScheme(); |
444 | } |
445 | else |
446 | cs = ColorSchemeManager::instance()->findColorScheme(name); |
447 | |
448 | if (! cs) |
449 | { |
450 | QMessageBox::information(this, |
451 | tr("Color Scheme Error" ), |
452 | tr("Cannot load color scheme: %1" ).arg(name)); |
453 | return; |
454 | } |
455 | ColorEntry table[TABLE_COLORS]; |
456 | cs->getColorTable(table); |
457 | m_impl->m_terminalDisplay->setColorTable(table); |
458 | } |
459 | |
460 | QStringList QTermWidget::availableColorSchemes() |
461 | { |
462 | QStringList ret; |
463 | const auto allColorSchemes = ColorSchemeManager::instance()->allColorSchemes(); |
464 | for (const ColorScheme* cs : allColorSchemes) |
465 | ret.append(cs->name()); |
466 | return ret; |
467 | } |
468 | |
469 | void QTermWidget::addCustomColorSchemeDir(const QString& custom_dir) |
470 | { |
471 | ColorSchemeManager::instance()->addCustomColorSchemeDir(custom_dir); |
472 | } |
473 | |
474 | void QTermWidget::setSize(const QSize &size) |
475 | { |
476 | m_impl->m_terminalDisplay->setSize(size.width(), size.height()); |
477 | } |
478 | |
479 | void QTermWidget::setHistorySize(int lines) |
480 | { |
481 | if (lines < 0) |
482 | m_impl->m_session->setHistoryType(HistoryTypeFile()); |
483 | else |
484 | m_impl->m_session->setHistoryType(HistoryTypeBuffer(lines)); |
485 | } |
486 | |
487 | void QTermWidget::setScrollBarPosition(ScrollBarPosition pos) |
488 | { |
489 | m_impl->m_terminalDisplay->setScrollBarPosition(pos); |
490 | } |
491 | |
492 | void QTermWidget::scrollToEnd() |
493 | { |
494 | m_impl->m_terminalDisplay->scrollToEnd(); |
495 | } |
496 | |
497 | void QTermWidget::sendText(const QString &text) |
498 | { |
499 | m_impl->m_session->sendText(text); |
500 | } |
501 | |
502 | void QTermWidget::resizeEvent(QResizeEvent*) |
503 | { |
504 | //qDebug("global window resizing...with %d %d", this->size().width(), this->size().height()); |
505 | m_impl->m_terminalDisplay->resize(this->size()); |
506 | } |
507 | |
508 | |
509 | void QTermWidget::sessionFinished() |
510 | { |
511 | emit finished(); |
512 | } |
513 | |
514 | void QTermWidget::bracketText(QString& text) |
515 | { |
516 | m_impl->m_terminalDisplay->bracketText(text); |
517 | } |
518 | |
519 | void QTermWidget::copyClipboard() |
520 | { |
521 | m_impl->m_terminalDisplay->copyClipboard(); |
522 | } |
523 | |
524 | void QTermWidget::pasteClipboard() |
525 | { |
526 | m_impl->m_terminalDisplay->pasteClipboard(); |
527 | } |
528 | |
529 | void QTermWidget::pasteSelection() |
530 | { |
531 | m_impl->m_terminalDisplay->pasteSelection(); |
532 | } |
533 | |
534 | void QTermWidget::setZoom(int step) |
535 | { |
536 | QFont font = m_impl->m_terminalDisplay->getVTFont(); |
537 | |
538 | font.setPointSize(font.pointSize() + step); |
539 | setTerminalFont(font); |
540 | } |
541 | |
542 | void QTermWidget::zoomIn() |
543 | { |
544 | setZoom(STEP_ZOOM); |
545 | } |
546 | |
547 | void QTermWidget::zoomOut() |
548 | { |
549 | setZoom(-STEP_ZOOM); |
550 | } |
551 | |
552 | void QTermWidget::setKeyBindings(const QString & kb) |
553 | { |
554 | m_impl->m_session->setKeyBindings(kb); |
555 | } |
556 | |
557 | void QTermWidget::clear() |
558 | { |
559 | m_impl->m_session->emulation()->reset(); |
560 | m_impl->m_session->refresh(); |
561 | m_impl->m_session->clearHistory(); |
562 | } |
563 | |
564 | void QTermWidget::setFlowControlEnabled(bool enabled) |
565 | { |
566 | m_impl->m_session->setFlowControlEnabled(enabled); |
567 | } |
568 | |
569 | QStringList QTermWidget::availableKeyBindings() |
570 | { |
571 | return KeyboardTranslatorManager::instance()->allTranslators(); |
572 | } |
573 | |
574 | QString QTermWidget::keyBindings() |
575 | { |
576 | return m_impl->m_session->keyBindings(); |
577 | } |
578 | |
579 | void QTermWidget::toggleShowSearchBar() |
580 | { |
581 | m_searchBar->isHidden() ? m_searchBar->show() : m_searchBar->hide(); |
582 | } |
583 | |
584 | bool QTermWidget::flowControlEnabled(void) |
585 | { |
586 | return m_impl->m_session->flowControlEnabled(); |
587 | } |
588 | |
589 | void QTermWidget::setFlowControlWarningEnabled(bool enabled) |
590 | { |
591 | if (flowControlEnabled()) { |
592 | // Do not show warning label if flow control is disabled |
593 | m_impl->m_terminalDisplay->setFlowControlWarningEnabled(enabled); |
594 | } |
595 | } |
596 | |
597 | void QTermWidget::setEnvironment(const QStringList& environment) |
598 | { |
599 | m_impl->m_session->setEnvironment(environment); |
600 | } |
601 | |
602 | void QTermWidget::setMotionAfterPasting(int action) |
603 | { |
604 | m_impl->m_terminalDisplay->setMotionAfterPasting((Konsole::MotionAfterPasting) action); |
605 | } |
606 | |
607 | int QTermWidget::historyLinesCount() |
608 | { |
609 | return m_impl->m_terminalDisplay->screenWindow()->screen()->getHistLines(); |
610 | } |
611 | |
612 | int QTermWidget::screenColumnsCount() |
613 | { |
614 | return m_impl->m_terminalDisplay->screenWindow()->screen()->getColumns(); |
615 | } |
616 | |
617 | int QTermWidget::screenLinesCount() |
618 | { |
619 | return m_impl->m_terminalDisplay->screenWindow()->screen()->getLines(); |
620 | } |
621 | |
622 | void QTermWidget::setSelectionStart(int row, int column) |
623 | { |
624 | m_impl->m_terminalDisplay->screenWindow()->screen()->setSelectionStart(column, row, true); |
625 | } |
626 | |
627 | void QTermWidget::setSelectionEnd(int row, int column) |
628 | { |
629 | m_impl->m_terminalDisplay->screenWindow()->screen()->setSelectionEnd(column, row); |
630 | } |
631 | |
632 | void QTermWidget::getSelectionStart(int& row, int& column) |
633 | { |
634 | m_impl->m_terminalDisplay->screenWindow()->screen()->getSelectionStart(column, row); |
635 | } |
636 | |
637 | void QTermWidget::getSelectionEnd(int& row, int& column) |
638 | { |
639 | m_impl->m_terminalDisplay->screenWindow()->screen()->getSelectionEnd(column, row); |
640 | } |
641 | |
642 | QString QTermWidget::selectedText(bool preserveLineBreaks) |
643 | { |
644 | return m_impl->m_terminalDisplay->screenWindow()->screen()->selectedText(preserveLineBreaks); |
645 | } |
646 | |
647 | void QTermWidget::setMonitorActivity(bool monitor) |
648 | { |
649 | m_impl->m_session->setMonitorActivity(monitor); |
650 | } |
651 | |
652 | void QTermWidget::setMonitorSilence(bool monitor) |
653 | { |
654 | m_impl->m_session->setMonitorSilence(monitor); |
655 | } |
656 | |
657 | void QTermWidget::setSilenceTimeout(int seconds) |
658 | { |
659 | m_impl->m_session->setMonitorSilenceSeconds(seconds); |
660 | } |
661 | |
662 | Filter::HotSpot* QTermWidget::getHotSpotAt(const QPoint &pos) const |
663 | { |
664 | int row = 0, column = 0; |
665 | m_impl->m_terminalDisplay->getCharacterPosition(pos, row, column); |
666 | return getHotSpotAt(row, column); |
667 | } |
668 | |
669 | Filter::HotSpot* QTermWidget::getHotSpotAt(int row, int column) const |
670 | { |
671 | return m_impl->m_terminalDisplay->filterChain()->hotSpotAt(row, column); |
672 | } |
673 | |
674 | QList<QAction*> QTermWidget::filterActions(const QPoint& position) |
675 | { |
676 | return m_impl->m_terminalDisplay->filterActions(position); |
677 | } |
678 | |
679 | int QTermWidget::getPtySlaveFd() const |
680 | { |
681 | return m_impl->m_session->getPtySlaveFd(); |
682 | } |
683 | |
684 | void QTermWidget::setKeyboardCursorShape(KeyboardCursorShape shape) |
685 | { |
686 | m_impl->m_terminalDisplay->setKeyboardCursorShape(shape); |
687 | } |
688 | |
689 | void QTermWidget::setBlinkingCursor(bool blink) |
690 | { |
691 | m_impl->m_terminalDisplay->setBlinkingCursor(blink); |
692 | } |
693 | |
694 | void QTermWidget::setBidiEnabled(bool enabled) |
695 | { |
696 | m_impl->m_terminalDisplay->setBidiEnabled(enabled); |
697 | } |
698 | |
699 | bool QTermWidget::isBidiEnabled() |
700 | { |
701 | return m_impl->m_terminalDisplay->isBidiEnabled(); |
702 | } |
703 | |
704 | QString QTermWidget::title() const |
705 | { |
706 | QString title = m_impl->m_session->userTitle(); |
707 | if (title.isEmpty()) |
708 | title = m_impl->m_session->title(Konsole::Session::NameRole); |
709 | return title; |
710 | } |
711 | |
712 | QString QTermWidget::icon() const |
713 | { |
714 | QString icon = m_impl->m_session->iconText(); |
715 | if (icon.isEmpty()) |
716 | icon = m_impl->m_session->iconName(); |
717 | return icon; |
718 | } |
719 | |
720 | bool QTermWidget::isTitleChanged() const |
721 | { |
722 | return m_impl->m_session->isTitleChanged(); |
723 | } |
724 | |
725 | void QTermWidget::setAutoClose(bool autoClose) |
726 | { |
727 | m_impl->m_session->setAutoClose(autoClose); |
728 | } |
729 | |
730 | void QTermWidget::cursorChanged(Konsole::Emulation::KeyboardCursorShape cursorShape, bool blinkingCursorEnabled) |
731 | { |
732 | // TODO: A switch to enable/disable DECSCUSR? |
733 | setKeyboardCursorShape(cursorShape); |
734 | setBlinkingCursor(blinkingCursorEnabled); |
735 | } |
736 | |
737 | void QTermWidget::setMargin(int margin) |
738 | { |
739 | m_impl->m_terminalDisplay->setMargin(margin); |
740 | } |
741 | |
742 | int QTermWidget::getMargin() const |
743 | { |
744 | return m_impl->m_terminalDisplay->margin(); |
745 | } |
746 | |