玉兔远程控制 0.1.0-alpha.2
载入中...
搜索中...
未找到
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
93{
94 QString szDescription;
95 if(!Name().isEmpty())
96 szDescription = tr("Name: ") + Name() + "\n";
97
98 if(!GetTypeName().isEmpty())
99 szDescription += tr("Type: ") + GetTypeName() + "\n";
100
101 if(!Protocol().isEmpty()) {
102 szDescription += tr("Protocol: ") + Protocol();
103#ifdef DEBUG
104 if(!GetPlugin()->DisplayName().isEmpty())
105 szDescription += " - " + GetPlugin()->DisplayName();
106#endif
107 szDescription += "\n";
108 }
109
110 if(GetSecurityLevel() != SecurityLevel::No)
111 szDescription += tr("Security level: ") + GetSecurityLevelString() + "\n";
112
113 if(!GetPlugin()->Description().isEmpty())
114 szDescription += tr("Description: ") + GetPlugin()->Description();
115
116 return szDescription;
117}
118
120{
121 return m_pTerminal;
122}
123
124CStats* COperateTerminal::GetStats()
125{
126 return &m_Stats;
127}
128
129int COperateTerminal::Load(QSettings &set)
130{
131 int nRet = 0;
132 auto pPara = GetParameter();
133 Q_ASSERT(pPara);
134 if(!pPara) return -1;
135 nRet = pPara->Load(set);
136 return nRet;
137}
138
139int COperateTerminal::Save(QSettings &set)
140{
141 int nRet = 0;
142 auto pPara = GetParameter();
143 Q_ASSERT(pPara);
144 if(!pPara) return -1;
145 nRet = pPara->Save(set);
146 return nRet;
147}
148
150{
151 int nRet = 0;
152
153 nRet = COperate::Initial();
154 if(nRet)
155 return nRet;
156
157 m_pEditCopy = m_Menu.addAction(QIcon::fromTheme("edit-copy"),
158 tr("Copy selection to clipboard") + "\tCtrl+Shift+C",
159 m_pTerminal, SLOT(copyClipboard()));
160 m_pEditPaste = m_Menu.addAction(QIcon::fromTheme("edit-paste"),
161 tr("Paste clipboard") + "\tCtrl+V",
162 m_pTerminal, SLOT(pasteClipboard()));
163 m_Menu.addAction(tr("Paste selection"), m_pTerminal, SLOT(pasteSelection()));
164 m_Menu.addSeparator();
165 m_pZoomIn = m_Menu.addAction(QIcon::fromTheme("zoom-in"), tr("Zoom in") + "\tCtrl++",
166 m_pTerminal, SLOT(zoomIn()));
167 m_pZoomOut = m_Menu.addAction(QIcon::fromTheme("zoom-out"), tr("Zoom out") + "\tCtrl+-",
168 m_pTerminal, SLOT(zoomOut()));
169 m_pZoomOriginal = m_Menu.addAction(QIcon::fromTheme("zoom-original"), tr("Zoom reset") + "\tCtrl+0",
170 this, SLOT(slotZoomReset()));
171
172 m_Menu.addSeparator();
173 // m_pActionOpenWithSystem = m_Menu.addAction(
174 // QIcon::fromTheme("folder-open"),
175 // tr("Open the selection with the System Associated Program"),
176 // QKeySequence(Qt::CTRL | Qt::Key_O),
177 // [&](){
178 // QString szText = m_pTerminal->selectedText(false);
179 // QUrl url(szText);
180 // qDebug(log) << szText << url;
181 // QDesktopServices::openUrl(url);
182 // });
183 m_pActionFind = m_Menu.addAction(
184 QIcon::fromTheme("edit-find"), tr("Find ......") + "\tCtrl+F",
185 m_pTerminal, &QTermWidget::toggleShowSearchBar);
186
187 m_Menu.addSeparator();
188 m_pClear = m_Menu.addAction(QIcon::fromTheme("edit-clear"),
189 tr("Clear") + "\tCtrl+R",
190 m_pTerminal, SLOT(clear()));
191
192 if(m_pActionSettings) {
193 m_Menu.addSeparator();
194 m_Menu.addAction(m_pActionSettings);
195 }
196
197 return nRet;
198}
199
201{
202 int nRet = 0;
203 nRet = COperate::Clean();
204 return nRet;
205}
206
207int COperateTerminal::Start()
208{
209 int nRet = 0;
210
211 slotUpdateParameter(this);
212 m_pThread = new CBackendThread(this);
213 if(!m_pThread) {
214 qCritical(log) << "new CBackendThread fail";
215 return -2;
216 }
217 m_pThread->start();
218 return nRet;
219}
220
221int COperateTerminal::Stop()
222{
223 qDebug(log) << Q_FUNC_INFO;
224 int nRet = 0;
225 if(m_pThread)
226 {
227 m_pThread->quit();
228 //Don't delete m_pThread, See CBackendThread
229 m_pThread = nullptr;
230 }
231 return nRet;
232}
233
235{
236 return m_pParameters;
237}
238
240{
241 int nRet = 0;
242
243 Q_ASSERT(pPara);
244 Q_ASSERT(!m_pParameters);
245
246 m_pParameters = pPara;
247
248 if(!pPara || !m_pTerminal) return -1;
249
250 bool check = connect(GetParameter(), &CParameter::sigChanged,
251 this, [&](){
252 emit this->sigUpdateParameters(this);
253 });
254 Q_ASSERT(check);
255 check = connect(this, SIGNAL(sigUpdateParameters(COperate*)),
256 this, SLOT(slotUpdateParameter(COperate*)));
257 Q_ASSERT(check);
258
259 return nRet;
260}
261
262void COperateTerminal::slotUpdateParameter(COperate* pOperate)
263{
264 qDebug(log) << Q_FUNC_INFO;
265 if(this != pOperate) return;
266 if(!GetParameter() || !m_pTerminal) return;
267
268 auto pPara = &GetParameter()->m_Terminal;
269
270#if QTERMWIDGET_VERSION >= QT_VERSION_CHECK(0, 9, 0)
271 m_pTerminal->setTerminalSizeHint(pPara->GetSizeHint());
272 m_pTerminal->setBidiEnabled(pPara->GetDirectional());
273 m_pTerminal->disableBracketedPasteMode(pPara->GetDisableBracketedPasteMode());
274#endif
275 m_pTerminal->setTerminalFont(pPara->GetFont());
276 m_pTerminal->setKeyboardCursorShape(pPara->GetCursorShape());
277 m_pTerminal->setColorScheme(pPara->GetColorScheme());
278 m_pTerminal->setScrollBarPosition(pPara->GetScrollBarPosition());
279 m_pTerminal->setFlowControlEnabled(pPara->GetFlowControl());
280 m_pTerminal->setFlowControlWarningEnabled(pPara->GetFlowControlWarning());
281 m_pTerminal->setMotionAfterPasting(pPara->GetMotionAfterPasting());
282 m_pTerminal->setTerminalOpacity(1.0 - pPara->GetTransparency() / 100.0);
283 m_pTerminal->setTerminalBackgroundImage(pPara->GetBackgroupImage());
284
285 m_pTerminal->setKeyBindings(pPara->GetKeyBindings());
286 m_pTerminal->setHistorySize(pPara->GetHistorySize());
287
288 // m_pTerminal->setMonitorActivity(false);
289 // m_pTerminal->setMonitorSilence(false);
290 // m_pTerminal->setBlinkingCursor(true);
291}
292
293void COperateTerminal::slotZoomReset()
294{
295 if(!m_pTerminal) return;
296 CParameterTerminal* pPara = &GetParameter()->m_Terminal;
297 if(!pPara) return;
298 m_pTerminal->setTerminalFont(pPara->GetFont());
299}
300
301void COperateTerminal::slotCustomContextMenu(const QPoint & pos)
302{
303 if(!m_pTerminal) return;
304
305 // QString szText = m_pTerminal->selectedText(false);
306 // m_pActionOpenWithSystem->setVisible(
307 // !szText.isEmpty()
308 // && QUrl(szText).isValid());
309 m_Menu.exec(m_pTerminal->mapToGlobal(pos));
310}
311
312void COperateTerminal::slotActivateUrl(const QUrl& url, bool fromContextMenu)
313{
314 if (QApplication::keyboardModifiers() & Qt::ControlModifier || fromContextMenu) {
315 QDesktopServices::openUrl(url);
316 }
317}
318
319void COperateTerminal::slotTermKeyPressed(QKeyEvent* e)
320{
321 qDebug(log) << Q_FUNC_INFO << e;
322}
323
324void COperateTerminal::slotFocusIn()
325{
327 SetShotcuts(true);
328}
329
330void COperateTerminal::slotFocusOut()
331{
332 SetShotcuts(false);
333}
334
335const qint16 COperateTerminal::Version() const
336{
337 return 0;
338}
339
340const QString COperateTerminal::Details()
341{
342 QString szDetails;
343 szDetails = "- " + tr("QTermWidget:") + " "
344 + QString("%1.%2.%3").arg(QTERMWIDGET_VERSION_MAJOR)
345 .arg(QTERMWIDGET_VERSION_MINOR)
346 .arg(QTERMWIDGET_VERSION_PATCH) + "\n";
347 return szDetails;
348}
349
351{
352 Q_ASSERT(pPara);
353 if(GetParameter())
354 {
355 GetParameter()->SetGlobalParameters(pPara);
356 return COperate::SetGlobalParameters(pPara);
357 } else {
358 QString szMsg = "There is not parameters! "
359 "please first create parameters, "
360 "then call SetParameter() in the ";
361 szMsg += metaObject()->className() + QString("::")
362 + metaObject()->className();
363 szMsg += QString("() or ") + metaObject()->className()
364 + QString("::") + "Initial()";
365 szMsg += " to set the parameters pointer. "
366 "Default set CParameterPlugin for the parameters of operate "
367 "(CParameterOperate or its derived classes) "
368 "See CManager::CreateOperate. "
369 "If you are sure the parameter of operate "
370 "does not need CParameterPlugin. "
371 "Please overload the SetGlobalParameters() in the ";
372 szMsg += QString(metaObject()->className()) + " . don't set it";
373 qCritical(log) << szMsg.toStdString().c_str();
374 Q_ASSERT(false);
375 }
376 return -1;
377}
378
379int COperateTerminal::WriteTerminal(const char *buf, int len)
380{
381 int nRet = 0;
382#if defined(Q_OS_WIN)
383 if(m_pTerminal) {
384 m_pTerminal->receiveData(buf, len);
385 }
386#else
387 nRet = write(m_pTerminal->getPtySlaveFd(), buf, len);
388#endif
389 return nRet;
390}
391
392void COperateTerminal::SetShotcuts(bool bEnable)
393{
394 if(bEnable) {
395 m_pEditCopy->setShortcuts(
396 QList<QKeySequence>() << QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_C)
397 << QKeySequence(Qt::CTRL | Qt::Key_Insert));
398 m_pEditPaste->setShortcuts(QList<QKeySequence>()
399 << QKeySequence(QKeySequence::Paste)
400 << QKeySequence(Qt::SHIFT | Qt::Key_Insert));
401 m_pZoomIn->setShortcut(QKeySequence(QKeySequence::ZoomIn));
402 m_pZoomOut->setShortcut(QKeySequence(QKeySequence::ZoomOut));
403 m_pZoomOriginal->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0));
404 m_pActionFind->setShortcut(QKeySequence(QKeySequence::Find));
405 m_pClear->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R));
406 return;
407 }
408
409 m_pEditCopy->setShortcuts(QList<QKeySequence>());
410 m_pEditPaste->setShortcut(QKeySequence());
411 m_pZoomIn->setShortcut(QKeySequence());
412 m_pZoomOut->setShortcut(QKeySequence());
413 m_pZoomOriginal->setShortcut(QKeySequence());
414 m_pActionFind->setShortcut(QKeySequence());
415 m_pClear->setShortcut(QKeySequence());
416}
417
418const QString COperateTerminal::Id()
419{
420 QString szId = COperate::Id();
421 if(GetParameter()) {
422 if(GetParameter()->GetName().isEmpty())
423 szId += "_" + Name();
424 else
425 szId += "_" + GetParameter()->GetName();
426 }
427 static QRegularExpression exp("[-@:/#%!^&* \\.]");
428 szId = szId.replace(exp, "_");
429 return szId;
430}
431
433{
434 QString szName;
435 if(GetParameter())
436 szName = GetParameter()->GetName();
437 if(szName.isEmpty())
438 szName = COperate::Name();
439 return szName;
440}
The backend thread
virtual void quit()
Quit
终端操作接口
virtual int Save(QSettings &set) override
保存参数
virtual const qint16 Version() const override
Version
virtual int Initial() override
Initial parameters and resource
virtual CParameterTerminalBase * GetParameter()
Get parameters
virtual const QString Name() override
Name
virtual int Clean() override
Clean parameters and resource
virtual int Load(QSettings &set) override
加载参数
virtual const QString Id() override
Identity
virtual int SetParameter(CParameterTerminalBase *pPara)
设置参数指针
virtual int SetGlobalParameters(CParameterPlugin *pPara) override
应用插件全局参数
virtual const QString Description() override
Description
QWidget * GetViewer() override
得到显示视图
操作接口。
Definition Operate.h:51
virtual Q_INVOKABLE int Initial()
Initial parameters and resource
Definition Operate.cpp:230
virtual const QString Protocol() const
Protocol
Definition Operate.cpp:71
virtual Q_INVOKABLE int SetGlobalParameters(CParameterPlugin *pPara)=0
应用插件全局参数
Definition Operate.cpp:264
virtual Q_INVOKABLE int Clean()
Clean parameters and resource
Definition Operate.cpp:247
void sigViewerFocusIn(QWidget *pView)
视图获得焦点
Q_INVOKABLE CPlugin * GetPlugin() const
Get plugin
Definition Operate.cpp:259
virtual const QString Name()
Name
Definition Operate.cpp:41
void sigUpdateParameters(COperate *pOperate)
更新参数,通知应用程序保存或显示参数
virtual const QString Id()
Identity
Definition Operate.cpp:33
virtual const QString GetTypeName() const
Get type name
Definition Operate.cpp:76
插件的全局参数。
void sigChanged()
当参数改变时,触发 通常如果需要,则相应的参数会对应一个改变事件。
插件接口
Definition Plugin.h:15
virtual const QString DisplayName() const
在界面上显示的名称
Definition Plugin.cpp:73
virtual const QString Description() const =0
描述
Definition Stats.h:11