Rabbit Remote Control 0.1.0-bate8
Loading...
Searching...
No Matches
OperateTerminal.cpp
1// Author: Kang Lin <kl222@126.com>
2
3#include <QDialog>
4#include <QApplication>
5#include <QSettings>
6#include <QLoggingCategory>
7#include <QDesktopServices>
8#include <QDir>
9
10#if defined(Q_OS_UNIX)
11#include <unistd.h>
12#endif
13
14#include "ParameterOperate.h"
15#include "Backend.h"
16#include "BackendThread.h"
17#include "OperateTerminal.h"
18#include "Plugin.h"
19
20static Q_LOGGING_CATEGORY(log, "Operate.Terminal")
21
23 : COperate(parent)
24 , m_pTerminal(nullptr)
25 , m_pThread(nullptr)
26 , m_pActionFind(nullptr)
27 , m_pActionOpenWithSystem(nullptr)
28 , m_pParameters(nullptr)
29 , m_pEditCopy(nullptr)
30 , m_pEditPaste(nullptr)
31 , m_pZoomIn(nullptr)
32 , m_pZoomOut(nullptr)
33 , m_pZoomOriginal(nullptr)
34 , m_pClear(nullptr)
35{
36 QTermWidget::addCustomColorSchemeDir(QApplication::applicationDirPath()
37 + QDir::separator() + "color-schemes");
38 QTermWidget::addCustomColorSchemeDir(QApplication::applicationDirPath()
39 + QDir::separator() + ".."
40 + QDir::separator() + "share"
41 + QDir::separator() + "qtermwidget6"
42 + QDir::separator() + "color-schemes");
43 /*QTermWidget::addCustomKeyboardLayoutDir(QApplication::applicationDirPath()
44 + QDir::separator() + "kb-layouts");
45 QTermWidget::addCustomKeyboardLayoutDir(QApplication::applicationDirPath()
46 + QDir::separator() + ".."
47 + QDir::separator() + "share"
48 + QDir::separator() + "qtermwidget6"
49 + QDir::separator() + "kb-layouts");//*/
50 m_pTerminal = new QTermWidget(0);
51 if(!m_pTerminal) {
52 qCritical(log) << "new QTermWidget() fail";
53 return;
54 }
55 m_pTerminal->setAutoClose(true);
56
57 bool check = false;
58 m_pTerminal->setContextMenuPolicy(Qt::CustomContextMenu);
59 check = connect(m_pTerminal, SIGNAL(customContextMenuRequested(const QPoint &)),
60 this, SLOT(slotCustomContextMenu(const QPoint &)));
61 Q_ASSERT(check);
62 check = connect(m_pTerminal, SIGNAL(urlActivated(const QUrl&, bool)),
63 this, SLOT(slotActivateUrl(const QUrl&, bool)));
64 Q_ASSERT(check);
65 // check = connect(m_pTerminal, SIGNAL(titleChanged()),
66 // this, SLOT(slotTerminalTitleChanged()));
67 // Q_ASSERT(check);
68 check = connect(m_pTerminal, SIGNAL(finished()),
69 this, SIGNAL(sigStop()));
70 Q_ASSERT(check);
71 // check = connect(m_pTerminal, SIGNAL(termKeyPressed(QKeyEvent*)),
72 // this, SLOT(slotTermKeyPressed(QKeyEvent*)));
73 // Q_ASSERT(check);
74 check = connect(m_pTerminal, SIGNAL(termGetFocus()),
75 this, SLOT(slotFocusIn()));
76 Q_ASSERT(check);
77 check = connect(m_pTerminal, SIGNAL(termLostFocus()),
78 this, SLOT(slotFocusOut()));
79 Q_ASSERT(check);
80}
81
82COperateTerminal::~COperateTerminal()
83{
84 qDebug(log) << Q_FUNC_INFO;
85 if(m_pTerminal)
86 {
87 m_pTerminal->deleteLater();
88 m_pTerminal = nullptr;
89 }
90}
91
92const QString COperateTerminal::Id()
93{
94 QString szId = COperate::Id();
95 if(GetParameter()) {
96 if(GetParameter()->GetName().isEmpty())
97 szId += "_" + Name();
98 else
99 szId += "_" + GetParameter()->GetName();
100 }
101 static QRegularExpression exp("[-@:/#%!^&* \\.]");
102 szId = szId.replace(exp, "_");
103 return szId;
104}
105
107{
108 QString szName;
109 if(GetParameter())
110 szName = GetParameter()->GetName();
111 if(szName.isEmpty())
112 szName = COperate::Name();
113 return szName;
114}
115
117{
118 QString szDescription;
119 if(!Name().isEmpty())
120 szDescription = tr("Name: ") + Name() + "\n";
121
122 if(!GetTypeName().isEmpty())
123 szDescription += tr("Type: ") + GetTypeName() + "\n";
124
125 if(!Protocol().isEmpty()) {
126 szDescription += tr("Protocol: ") + Protocol();
127#ifdef DEBUG
128 if(!GetPlugin()->DisplayName().isEmpty())
129 szDescription += " - " + GetPlugin()->DisplayName();
130#endif
131 szDescription += "\n";
132 }
133
135 if(GetSecurityLevel() != CSecurityLevel::Level::No) {
136 szDescription += tr("Security level: ");
137 if(!sl.GetUnicodeIcon().isEmpty())
138 szDescription += sl.GetUnicodeIcon() + " ";
139 szDescription += sl.GetString() + "\n";
140 }
141
142 if(!GetPlugin()->Description().isEmpty())
143 szDescription += tr("Description: ") + GetPlugin()->Description();
144
145 return szDescription;
146}
147
148const qint16 COperateTerminal::Version() const
149{
150 return 0;
151}
152
153const QString COperateTerminal::Details()
154{
155 QString szDetails;
156 szDetails = " - " + tr("QTermWidget") + "\n" +
157 " - " + tr("Version:") + " " + QString("%1.%2.%3").arg(QTERMWIDGET_VERSION_MAJOR)
158 .arg(QTERMWIDGET_VERSION_MINOR)
159 .arg(QTERMWIDGET_VERSION_PATCH) + "\n";
160 return szDetails;
161}
162
164{
165 return m_pTerminal;
166}
167
169{
170 return &m_Stats;
171}
172
173int COperateTerminal::Load(QSettings &set)
174{
175 int nRet = 0;
176 auto pPara = GetParameter();
177 Q_ASSERT(pPara);
178 if(!pPara) return -1;
179 nRet = pPara->Load(set);
180 return nRet;
181}
182
183int COperateTerminal::Save(QSettings &set)
184{
185 int nRet = 0;
186 auto pPara = GetParameter();
187 Q_ASSERT(pPara);
188 if(!pPara) return -1;
189 nRet = pPara->Save(set);
190 return nRet;
191}
192
194{
195 int nRet = 0;
196
197 nRet = COperate::Initial();
198 if(nRet)
199 return nRet;
200
201 m_pEditCopy = m_Menu.addAction(QIcon::fromTheme("edit-copy"),
202 tr("Copy selection to clipboard") + "\tCtrl+Shift+C",
203 m_pTerminal, SLOT(copyClipboard()));
204 m_pEditPaste = m_Menu.addAction(QIcon::fromTheme("edit-paste"),
205 tr("Paste clipboard") + "\tCtrl+V",
206 m_pTerminal, SLOT(pasteClipboard()));
207 m_Menu.addAction(tr("Paste selection"), m_pTerminal, SLOT(pasteSelection()));
208 m_Menu.addSeparator();
209 m_pZoomIn = m_Menu.addAction(QIcon::fromTheme("zoom-in"), tr("Zoom in") + "\tCtrl++",
210 m_pTerminal, SLOT(zoomIn()));
211 m_pZoomOut = m_Menu.addAction(QIcon::fromTheme("zoom-out"), tr("Zoom out") + "\tCtrl+-",
212 m_pTerminal, SLOT(zoomOut()));
213 m_pZoomOriginal = m_Menu.addAction(QIcon::fromTheme("zoom-original"), tr("Zoom reset") + "\tCtrl+0",
214 this, SLOT(slotZoomReset()));
215
216 m_Menu.addSeparator();
217 // m_pActionOpenWithSystem = m_Menu.addAction(
218 // QIcon::fromTheme("folder-open"),
219 // tr("Open the selection with the System Associated Program"),
220 // QKeySequence(Qt::CTRL | Qt::Key_O),
221 // [&](){
222 // QString szText = m_pTerminal->selectedText(false);
223 // QUrl url(szText);
224 // qDebug(log) << szText << url;
225 // QDesktopServices::openUrl(url);
226 // });
227 m_pActionFind = m_Menu.addAction(
228 QIcon::fromTheme("edit-find"), tr("Find ......") + "\tCtrl+F",
229 m_pTerminal, &QTermWidget::toggleShowSearchBar);
230
231 m_Menu.addSeparator();
232 m_pClear = m_Menu.addAction(QIcon::fromTheme("edit-clear"),
233 tr("Clear") + "\tCtrl+R",
234 m_pTerminal, SLOT(clear()));
235
236 if(m_pActionSettings) {
237 m_Menu.addSeparator();
238 m_Menu.addAction(m_pActionSettings);
239 }
240
241 return nRet;
242}
243
245{
246 int nRet = 0;
247 nRet = COperate::Clean();
248 return nRet;
249}
250
251int COperateTerminal::Start()
252{
253 int nRet = 0;
254
255 slotUpdateParameter(this);
256 m_pThread = new CBackendThread(this);
257 if(!m_pThread) {
258 qCritical(log) << "new CBackendThread fail";
259 return -2;
260 }
261 m_pThread->start();
262 return nRet;
263}
264
265int COperateTerminal::Stop()
266{
267 qDebug(log) << Q_FUNC_INFO;
268 int nRet = 0;
269 if(m_pThread)
270 {
271 m_pThread->quit();
272 //Don't delete m_pThread, See CBackendThread
273 m_pThread = nullptr;
274 }
275 return nRet;
276}
277
279{
280 return m_pParameters;
281}
282
284{
285 int nRet = 0;
286
287 Q_ASSERT(pPara);
288 Q_ASSERT(!m_pParameters);
289
290 m_pParameters = pPara;
291
292 if(!pPara || !m_pTerminal) return -1;
293
294 bool check = connect(GetParameter(), &CParameter::sigChanged,
295 this, [&](){
296 emit this->sigUpdateParameters(this);
297 });
298 Q_ASSERT(check);
299 check = connect(this, SIGNAL(sigUpdateParameters(COperate*)),
300 this, SLOT(slotUpdateParameter(COperate*)));
301 Q_ASSERT(check);
302
303 return nRet;
304}
305
306void COperateTerminal::slotUpdateParameter(COperate* pOperate)
307{
308 qDebug(log) << Q_FUNC_INFO;
309 if(this != pOperate) return;
310 if(!GetParameter() || !m_pTerminal) return;
311
312 auto pPara = &GetParameter()->m_Terminal;
313
314#if QTERMWIDGET_VERSION >= QT_VERSION_CHECK(0, 9, 0)
315 m_pTerminal->setTerminalSizeHint(pPara->GetSizeHint());
316 m_pTerminal->setBidiEnabled(pPara->GetDirectional());
317 m_pTerminal->disableBracketedPasteMode(pPara->GetDisableBracketedPasteMode());
318#endif
319 m_pTerminal->setTerminalFont(pPara->GetFont());
320 m_pTerminal->setKeyboardCursorShape(pPara->GetCursorShape());
321 m_pTerminal->setColorScheme(pPara->GetColorScheme());
322 m_pTerminal->setScrollBarPosition(pPara->GetScrollBarPosition());
323 m_pTerminal->setFlowControlEnabled(pPara->GetFlowControl());
324 m_pTerminal->setFlowControlWarningEnabled(pPara->GetFlowControlWarning());
325 m_pTerminal->setMotionAfterPasting(pPara->GetMotionAfterPasting());
326 m_pTerminal->setTerminalOpacity(1.0 - pPara->GetTransparency() / 100.0);
327 m_pTerminal->setTerminalBackgroundImage(pPara->GetBackgroupImage());
328
329 m_pTerminal->setKeyBindings(pPara->GetKeyBindings());
330 m_pTerminal->setHistorySize(pPara->GetHistorySize());
331
332 // m_pTerminal->setMonitorActivity(false);
333 // m_pTerminal->setMonitorSilence(false);
334 // m_pTerminal->setBlinkingCursor(true);
335}
336
337void COperateTerminal::slotZoomReset()
338{
339 if(!m_pTerminal) return;
340 CParameterTerminal* pPara = &GetParameter()->m_Terminal;
341 if(!pPara) return;
342 m_pTerminal->setTerminalFont(pPara->GetFont());
343}
344
345void COperateTerminal::slotCustomContextMenu(const QPoint & pos)
346{
347 if(!m_pTerminal) return;
348
349 // QString szText = m_pTerminal->selectedText(false);
350 // m_pActionOpenWithSystem->setVisible(
351 // !szText.isEmpty()
352 // && QUrl(szText).isValid());
353 m_Menu.exec(m_pTerminal->mapToGlobal(pos));
354}
355
356void COperateTerminal::slotActivateUrl(const QUrl& url, bool fromContextMenu)
357{
358 if (QApplication::keyboardModifiers() & Qt::ControlModifier || fromContextMenu) {
359 QDesktopServices::openUrl(url);
360 }
361}
362
363void COperateTerminal::slotTermKeyPressed(QKeyEvent* e)
364{
365 qDebug(log) << Q_FUNC_INFO << e;
366}
367
368void COperateTerminal::slotFocusIn()
369{
371 SetShotcuts(true);
372}
373
374void COperateTerminal::slotFocusOut()
375{
376 SetShotcuts(false);
377}
378
380{
381 Q_ASSERT(pPara);
382 if(GetParameter()) {
383 GetParameter()->SetGlobalParameters(pPara);
384 if(pPara) {
385 bool check = connect(pPara, SIGNAL(sigNameStylesChanged()),
386 this, SLOT(slotUpdateName()));
387 Q_ASSERT(check);
388 }
389 return 0;
390 } else {
391 QString szMsg = "There is not parameters! "
392 "please first create parameters, "
393 "then call SetParameter() in the ";
394 szMsg += metaObject()->className() + QString("::")
395 + metaObject()->className();
396 szMsg += QString("() or ") + metaObject()->className()
397 + QString("::") + "Initial()";
398 szMsg += " to set the parameters pointer. "
399 "Default set CParameterPlugin for the parameters of operate "
400 "(CParameterOperate or its derived classes) "
401 "See CManager::CreateOperate. "
402 "If you are sure the parameter of operate "
403 "does not need CParameterPlugin. "
404 "Please overload the SetGlobalParameters() in the ";
405 szMsg += QString(metaObject()->className()) + " . don't set it";
406 qCritical(log) << szMsg.toStdString().c_str();
407 Q_ASSERT(false);
408 }
409 return -1;
410}
411
412int COperateTerminal::WriteTerminal(const char *buf, int len)
413{
414 int nRet = 0;
415#if defined(Q_OS_WIN)
416 if(m_pTerminal) {
417 m_pTerminal->receiveData(buf, len);
418 }
419#else
420 nRet = write(m_pTerminal->getPtySlaveFd(), buf, len);
421#endif
422 return nRet;
423}
424
425void COperateTerminal::SetShotcuts(bool bEnable)
426{
427 if(bEnable) {
428 m_pEditCopy->setShortcuts(
429 QList<QKeySequence>() << QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_C)
430 << QKeySequence(Qt::CTRL | Qt::Key_Insert));
431 m_pEditPaste->setShortcuts(QList<QKeySequence>()
432 << QKeySequence(QKeySequence::Paste)
433 << QKeySequence(Qt::SHIFT | Qt::Key_Insert));
434 m_pZoomIn->setShortcut(QKeySequence(QKeySequence::ZoomIn));
435 m_pZoomOut->setShortcut(QKeySequence(QKeySequence::ZoomOut));
436 m_pZoomOriginal->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0));
437 m_pActionFind->setShortcut(QKeySequence(QKeySequence::Find));
438 m_pClear->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R));
439 return;
440 }
441
442 m_pEditCopy->setShortcuts(QList<QKeySequence>());
443 m_pEditPaste->setShortcut(QKeySequence());
444 m_pZoomIn->setShortcut(QKeySequence());
445 m_pZoomOut->setShortcut(QKeySequence());
446 m_pZoomOriginal->setShortcut(QKeySequence());
447 m_pActionFind->setShortcut(QKeySequence());
448 m_pClear->setShortcut(QKeySequence());
449}
450
The backend thread.
virtual void quit()
Quit.
Terminal operate interface.
virtual int Save(QSettings &set) override
Save parameters.
CStats * GetStats() override
Get statistics.
virtual int Initial() override
Initial parameters and resource.
virtual const QString Name() override
Name.
virtual int Clean() override
Clean parameters and resource.
virtual int Load(QSettings &set) override
Load parameters.
virtual int SetParameter(CParameterTerminalBase *pPara)
Set parameter pointer.
virtual CParameterTerminalBase * GetParameter() const
Get parameters.
virtual int SetGlobalParameters(CParameterPlugin *pPara) override
Set Global Parameters.
virtual const QString Description() override
Description.
QWidget * GetViewer() override
Get Viewer.
Operate interface.
Definition Operate.h:51
virtual CSecurityLevel::Levels GetSecurityLevel() const
Get Security Level.
Definition Operate.cpp:129
virtual Q_INVOKABLE int Initial()
Initial parameters and resource.
Definition Operate.cpp:190
virtual Q_INVOKABLE int Clean()
Clean parameters and resource.
Definition Operate.cpp:207
void sigViewerFocusIn(QWidget *pView)
The view is focus.
Q_INVOKABLE CPlugin * GetPlugin() const
Get plugin.
Definition Operate.cpp:219
virtual const QString Name()
Name.
Definition Operate.cpp:46
void sigUpdateParameters(COperate *pOperate)
Update parameters, notify application to save or show parameters.
Global parameters of plugins.
Terminal base parameter.
void sigChanged()
emit when the parameter changes Usually if required, the corresponding parameter corresponds to a cha...
Plugin interface.
Definition Plugin.h:15
virtual const QString DisplayName() const
The plugin display name.
Definition Plugin.cpp:76
virtual const QString Description() const =0
Plugin description.
Security level.
Definition Stats.h:79
Definition Stats.h:11