Rabbit Remote Control 0.1.0-alpha
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
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
124int COperateTerminal::Load(QSettings &set)
125{
126 int nRet = 0;
127 auto pPara = GetParameter();
128 Q_ASSERT(pPara);
129 if(!pPara) return -1;
130 nRet = pPara->Load(set);
131 return nRet;
132}
133
134int COperateTerminal::Save(QSettings &set)
135{
136 int nRet = 0;
137 auto pPara = GetParameter();
138 Q_ASSERT(pPara);
139 if(!pPara) return -1;
140 nRet = pPara->Save(set);
141 return nRet;
142}
143
145{
146 int nRet = 0;
147
148 nRet = COperate::Initial();
149 if(nRet)
150 return nRet;
151
152 m_pEditCopy = m_Menu.addAction(QIcon::fromTheme("edit-copy"),
153 tr("Copy selection to clipboard") + "\tCtrl+Shift+C",
154 m_pTerminal, SLOT(copyClipboard()));
155 m_pEditPaste = m_Menu.addAction(QIcon::fromTheme("edit-paste"),
156 tr("Paste clipboard") + "\tCtrl+V",
157 m_pTerminal, SLOT(pasteClipboard()));
158 m_Menu.addAction(tr("Paste selection"), m_pTerminal, SLOT(pasteSelection()));
159 m_Menu.addSeparator();
160 m_pZoomIn = m_Menu.addAction(QIcon::fromTheme("zoom-in"), tr("Zoom in") + "\tCtrl++",
161 m_pTerminal, SLOT(zoomIn()));
162 m_pZoomOut = m_Menu.addAction(QIcon::fromTheme("zoom-out"), tr("Zoom out") + "\tCtrl+-",
163 m_pTerminal, SLOT(zoomOut()));
164 m_pZoomOriginal = m_Menu.addAction(QIcon::fromTheme("zoom-original"), tr("Zoom reset") + "\tCtrl+0",
165 this, SLOT(slotZoomReset()));
166
167 m_Menu.addSeparator();
168 // m_pActionOpenWithSystem = m_Menu.addAction(
169 // QIcon::fromTheme("folder-open"),
170 // tr("Open the selection with the System Associated Program"),
171 // QKeySequence(Qt::CTRL | Qt::Key_O),
172 // [&](){
173 // QString szText = m_pTerminal->selectedText(false);
174 // QUrl url(szText);
175 // qDebug(log) << szText << url;
176 // QDesktopServices::openUrl(url);
177 // });
178 m_pActionFind = m_Menu.addAction(
179 QIcon::fromTheme("edit-find"), tr("Find ......") + "\tCtrl+F",
180 m_pTerminal, &QTermWidget::toggleShowSearchBar);
181
182 m_Menu.addSeparator();
183 m_pClear = m_Menu.addAction(QIcon::fromTheme("edit-clear"),
184 tr("Clear") + "\tCtrl+R",
185 m_pTerminal, SLOT(clear()));
186
187 if(m_pActionSettings) {
188 m_Menu.addSeparator();
189 m_Menu.addAction(m_pActionSettings);
190 }
191
192 return nRet;
193}
194
196{
197 int nRet = 0;
198 nRet = COperate::Clean();
199 return nRet;
200}
201
202int COperateTerminal::Start()
203{
204 int nRet = 0;
205
206 slotUpdateParameter(this);
207 m_pThread = new CBackendThread(this);
208 if(!m_pThread) {
209 qCritical(log) << "new CBackendThread fail";
210 return -2;
211 }
212 m_pThread->start();
213 return nRet;
214}
215
216int COperateTerminal::Stop()
217{
218 qDebug(log) << Q_FUNC_INFO;
219 int nRet = 0;
220 if(m_pThread)
221 {
222 m_pThread->quit();
223 //Don't delete m_pThread, See CBackendThread
224 m_pThread = nullptr;
225 }
226 return nRet;
227}
228
230{
231 return m_pParameters;
232}
233
235{
236 int nRet = 0;
237
238 Q_ASSERT(pPara);
239 Q_ASSERT(!m_pParameters);
240
241 m_pParameters = pPara;
242
243 if(!pPara || !m_pTerminal) return -1;
244
245 bool check = connect(GetParameter(), &CParameter::sigChanged,
246 this, [&](){
247 emit this->sigUpdateParameters(this);
248 });
249 Q_ASSERT(check);
250 check = connect(this, SIGNAL(sigUpdateParameters(COperate*)),
251 this, SLOT(slotUpdateParameter(COperate*)));
252 Q_ASSERT(check);
253
254 return nRet;
255}
256
257void COperateTerminal::slotUpdateParameter(COperate* pOperate)
258{
259 qDebug(log) << Q_FUNC_INFO;
260 if(this != pOperate) return;
261 if(!GetParameter() || !m_pTerminal) return;
262
263 auto pPara = &GetParameter()->m_Terminal;
264
265#if QTERMWIDGET_VERSION >= QT_VERSION_CHECK(0, 9, 0)
266 m_pTerminal->setTerminalSizeHint(pPara->GetSizeHint());
267 m_pTerminal->setBidiEnabled(pPara->GetDirectional());
268 m_pTerminal->disableBracketedPasteMode(pPara->GetDisableBracketedPasteMode());
269#endif
270 m_pTerminal->setTerminalFont(pPara->GetFont());
271 m_pTerminal->setKeyboardCursorShape(pPara->GetCursorShape());
272 m_pTerminal->setColorScheme(pPara->GetColorScheme());
273 m_pTerminal->setScrollBarPosition(pPara->GetScrollBarPosition());
274 m_pTerminal->setFlowControlEnabled(pPara->GetFlowControl());
275 m_pTerminal->setFlowControlWarningEnabled(pPara->GetFlowControlWarning());
276 m_pTerminal->setMotionAfterPasting(pPara->GetMotionAfterPasting());
277 m_pTerminal->setTerminalOpacity(1.0 - pPara->GetTransparency() / 100.0);
278 m_pTerminal->setTerminalBackgroundImage(pPara->GetBackgroupImage());
279
280 m_pTerminal->setKeyBindings(pPara->GetKeyBindings());
281 m_pTerminal->setHistorySize(pPara->GetHistorySize());
282
283 // m_pTerminal->setMonitorActivity(false);
284 // m_pTerminal->setMonitorSilence(false);
285 // m_pTerminal->setBlinkingCursor(true);
286}
287
288void COperateTerminal::slotZoomReset()
289{
290 if(!m_pTerminal) return;
291 CParameterTerminal* pPara = &GetParameter()->m_Terminal;
292 if(!pPara) return;
293 m_pTerminal->setTerminalFont(pPara->GetFont());
294}
295
296void COperateTerminal::slotCustomContextMenu(const QPoint & pos)
297{
298 if(!m_pTerminal) return;
299
300 // QString szText = m_pTerminal->selectedText(false);
301 // m_pActionOpenWithSystem->setVisible(
302 // !szText.isEmpty()
303 // && QUrl(szText).isValid());
304 m_Menu.exec(m_pTerminal->mapToGlobal(pos));
305}
306
307void COperateTerminal::slotActivateUrl(const QUrl& url, bool fromContextMenu)
308{
309 if (QApplication::keyboardModifiers() & Qt::ControlModifier || fromContextMenu) {
310 QDesktopServices::openUrl(url);
311 }
312}
313
314void COperateTerminal::slotTermKeyPressed(QKeyEvent* e)
315{
316 qDebug(log) << Q_FUNC_INFO << e;
317}
318
319void COperateTerminal::slotFocusIn()
320{
322 SetShotcuts(true);
323}
324
325void COperateTerminal::slotFocusOut()
326{
327 SetShotcuts(false);
328}
329
330const qint16 COperateTerminal::Version() const
331{
332 return 0;
333}
334
335const QString COperateTerminal::Details()
336{
337 QString szDetails;
338 szDetails = "- " + tr("QTermWidget:") + " "
339 + QString("%1.%2.%3").arg(QTERMWIDGET_VERSION_MAJOR)
340 .arg(QTERMWIDGET_VERSION_MINOR)
341 .arg(QTERMWIDGET_VERSION_PATCH) + "\n";
342 return szDetails;
343}
344
346{
347 Q_ASSERT(pPara);
348 if(GetParameter())
349 {
350 GetParameter()->SetGlobalParameters(pPara);
351 return COperate::SetGlobalParameters(pPara);
352 } else {
353 QString szMsg = "There is not parameters! "
354 "please first create parameters, "
355 "then call SetParameter() in the ";
356 szMsg += metaObject()->className() + QString("::")
357 + metaObject()->className();
358 szMsg += QString("() or ") + metaObject()->className()
359 + QString("::") + "Initial()";
360 szMsg += " to set the parameters pointer. "
361 "Default set CParameterPlugin for the parameters of operate "
362 "(CParameterOperate or its derived classes) "
363 "See CManager::CreateOperate. "
364 "If you are sure the parameter of operate "
365 "does not need CParameterPlugin. "
366 "Please overload the SetGlobalParameters() in the ";
367 szMsg += QString(metaObject()->className()) + " . don't set it";
368 qCritical(log) << szMsg.toStdString().c_str();
369 Q_ASSERT(false);
370 }
371 return -1;
372}
373
374int COperateTerminal::WriteTerminal(const char *buf, int len)
375{
376 int nRet = 0;
377#if defined(Q_OS_WIN)
378 if(m_pTerminal) {
379 m_pTerminal->receiveData(buf, len);
380 }
381#else
382 nRet = write(m_pTerminal->getPtySlaveFd(), buf, len);
383#endif
384 return nRet;
385}
386
387void COperateTerminal::SetShotcuts(bool bEnable)
388{
389 if(bEnable) {
390 m_pEditCopy->setShortcuts(
391 QList<QKeySequence>() << QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_C)
392 << QKeySequence(Qt::CTRL | Qt::Key_Insert));
393 m_pEditPaste->setShortcuts(QList<QKeySequence>()
394 << QKeySequence(QKeySequence::Paste)
395 << QKeySequence(Qt::SHIFT | Qt::Key_Insert));
396 m_pZoomIn->setShortcut(QKeySequence(QKeySequence::ZoomIn));
397 m_pZoomOut->setShortcut(QKeySequence(QKeySequence::ZoomOut));
398 m_pZoomOriginal->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0));
399 m_pActionFind->setShortcut(QKeySequence(QKeySequence::Find));
400 m_pClear->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R));
401 return;
402 }
403
404 m_pEditCopy->setShortcuts(QList<QKeySequence>());
405 m_pEditPaste->setShortcut(QKeySequence());
406 m_pZoomIn->setShortcut(QKeySequence());
407 m_pZoomOut->setShortcut(QKeySequence());
408 m_pZoomOriginal->setShortcut(QKeySequence());
409 m_pActionFind->setShortcut(QKeySequence());
410 m_pClear->setShortcut(QKeySequence());
411}
412
413const QString COperateTerminal::Id()
414{
415 QString szId = COperate::Id();
416 if(GetParameter()) {
417 if(GetParameter()->GetName().isEmpty())
418 szId += "_" + Name();
419 else
420 szId += "_" + GetParameter()->GetName();
421 }
422 static QRegularExpression exp("[-@:/#%!^&* \\.]");
423 szId = szId.replace(exp, "_");
424 return szId;
425}
426
428{
429 QString szName;
430 if(GetParameter())
431 szName = GetParameter()->GetName();
432 if(szName.isEmpty())
433 szName = COperate::Name();
434 return szName;
435}
The backend thread.
virtual void quit()
Quit.
Terminal operate interface.
virtual int Save(QSettings &set) override
Save parameters.
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
Load parameters.
virtual const QString Id() override
Identity.
virtual int SetParameter(CParameterTerminalBase *pPara)
Set parameter pointer.
virtual int SetGlobalParameters(CParameterPlugin *pPara) override
Apply the global parameters of the plug-in.
virtual const QString Description() override
Description.
QWidget * GetViewer() override
Get Viewer.
Operate interface.
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
Apply the global parameters of the plug-in.
Definition Operate.cpp:264
virtual Q_INVOKABLE int Clean()
Clean parameters and resource.
Definition Operate.cpp:247
void sigViewerFocusIn(QWidget *pView)
The view is focus.
Q_INVOKABLE CPlugin * GetPlugin() const
Get plugin.
Definition Operate.cpp:259
virtual const QString Name()
Name.
Definition Operate.cpp:41
void sigUpdateParameters(COperate *pOperate)
Update parameters, notify application to save or show parameters.
virtual const QString Id()
Identity.
Definition Operate.cpp:33
virtual const QString GetTypeName() const
Get type name.
Definition Operate.cpp:76
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:73
virtual const QString Description() const =0
Plugin description.