QtPass: src/qtpass.cpp Source File

Logo
QtPass 1.4.0
Multi-platform GUI for pass, the standard unix password manager.
Loading...
Searching...
No Matches
qtpass.cpp
Go to the documentation of this file.
1#include "qtpass.h"
2#include "mainwindow.h"
3#include "qtpasssettings.h"
4#include "util.h"
5#include <QApplication>
6#include <QClipboard>
7#include <QDialog>
8#include <QLabel>
9#include <QPixmap>
10#include <QVBoxLayout>
11
12#ifndef Q_OS_WIN
13#include <QInputDialog>
14#include <QLineEdit>
15#include <utility>
16#else
17#define WIN32_LEAN_AND_MEAN /*_KILLING_MACHINE*/
18#define WIN32_EXTRA_LEAN
19#include <windows.h>
20#include <winnetwk.h>
21#undef DELETE
22#endif
23
24#ifdef QT_DEBUG
25#include "debughelper.h"
26#endif
27
28 QtPass::QtPass(MainWindow *mainWindow)
29 : m_mainWindow(mainWindow), clippedText(QString()), freshStart(true) {
30 setClipboardTimer();
31 clearClipboardTimer.setSingleShot(true);
32 connect(&clearClipboardTimer, SIGNAL(timeout()), this,
33 SLOT(clearClipboard()));
34
35 QObject::connect(qApp, &QApplication::aboutToQuit, this,
36 &QtPass::clearClipboard);
37
38 setMainWindow();
39}
40
44 QtPass::~QtPass() {
45#ifdef Q_OS_WIN
46 if (QtPassSettings::isUseWebDav())
47 WNetCancelConnection2A(QtPassSettings::getPassStore().toUtf8().constData(),
48 0, 1);
49#else
50 if (fusedav.state() == QProcess::Running) {
51 fusedav.terminate();
52 fusedav.waitForFinished(2000);
53 }
54#endif
55}
56
61 bool QtPass::init() {
62 QString passStore = QtPassSettings::getPassStore(Util::findPasswordStore());
63 QtPassSettings::setPassStore(passStore);
64
65 QtPassSettings::initExecutables();
66
67 QString version = QtPassSettings::getVersion();
68 // dbg()<< version;
69
70 // Config updates
71 if (version.isEmpty()) {
72#ifdef QT_DEBUG
73 dbg() << "assuming fresh install";
74#endif
75
76 if (QtPassSettings::getAutoclearSeconds() < 5)
77 QtPassSettings::setAutoclearSeconds(10);
78 if (QtPassSettings::getAutoclearPanelSeconds() < 5)
79 QtPassSettings::setAutoclearPanelSeconds(10);
80 if (!QtPassSettings::getPwgenExecutable().isEmpty())
81 QtPassSettings::setUsePwgen(true);
82 else
83 QtPassSettings::setUsePwgen(false);
84 QtPassSettings::setPassTemplate("login\nurl");
85 } else {
86 // QStringList ver = version.split(".");
87 // dbg()<< ver;
88 // if (ver[0] == "0" && ver[1] == "8") {
90 // }
91 if (QtPassSettings::getPassTemplate().isEmpty())
92 QtPassSettings::setPassTemplate("login\nurl");
93 }
94
95 QtPassSettings::setVersion(VERSION);
96
97 if (Util::checkConfig()) {
98 m_mainWindow->config();
99 if (freshStart && Util::checkConfig())
100 return false;
101 }
102
103 // TODO(annejan): this needs to be before we try to access the store,
104 // but it would be better to do it after the Window is shown,
105 // as the long delay it can cause is irritating otherwise.
106 if (QtPassSettings::isUseWebDav())
107 mountWebDav();
108
109 freshStart = false;
110 // startupPhase = false;
111 return true;
112}
113
114void QtPass::setMainWindow(void) {
115 m_mainWindow->restoreWindow();
116
117 fusedav.setParent(m_mainWindow);
118
119 // TODO(bezet): this should be reconnected dynamically when pass changes
120 connectPassSignalHandlers(QtPassSettings::getRealPass());
121 connectPassSignalHandlers(QtPassSettings::getImitatePass());
122
123 connect(m_mainWindow, &MainWindow::passShowHandlerFinished, this,
124 &QtPass::passShowHandlerFinished);
125
126 // only for ipass
127 connect(QtPassSettings::getImitatePass(), &ImitatePass::startReencryptPath,
128 m_mainWindow, &MainWindow::startReencryptPath);
129 connect(QtPassSettings::getImitatePass(), &ImitatePass::endReencryptPath,
130 m_mainWindow, &MainWindow::endReencryptPath);
131
132 connect(m_mainWindow, &MainWindow::passGitInitNeeded, [=]() {
133#ifdef QT_DEBUG
134 dbg() << "Pass git init called";
135#endif
136 QtPassSettings::getPass()->GitInit();
137 });
138
139 connect(m_mainWindow, &MainWindow::generateGPGKeyPair, m_mainWindow,
140 [=](const QString &batch) {
141 QtPassSettings::getPass()->GenerateGPGKeys(batch);
142 m_mainWindow->showStatusMessage(tr("Generating GPG key pair"),
143 60000);
144 });
145}
146
147void QtPass::connectPassSignalHandlers(Pass *pass) {
148 connect(pass, &Pass::error, this, &QtPass::processError);
149 connect(pass, &Pass::processErrorExit, this, &QtPass::processErrorExit);
150 connect(pass, &Pass::critical, m_mainWindow, &MainWindow::critical);
151 connect(pass, &Pass::startingExecuteWrapper, m_mainWindow,
152 &MainWindow::executeWrapperStarted);
153 connect(pass, &Pass::statusMsg, m_mainWindow, &MainWindow::showStatusMessage);
154 connect(pass, &Pass::finishedShow, m_mainWindow,
155 &MainWindow::passShowHandler);
156 connect(pass, &Pass::finishedOtpGenerate, m_mainWindow,
157 &MainWindow::passOtpHandler);
158
159 connect(pass, &Pass::finishedGitInit, this, &QtPass::passStoreChanged);
160 connect(pass, &Pass::finishedGitPull, this, &QtPass::processFinished);
161 connect(pass, &Pass::finishedGitPush, this, &QtPass::processFinished);
162 connect(pass, &Pass::finishedInsert, this, &QtPass::finishedInsert);
163 connect(pass, &Pass::finishedRemove, this, &QtPass::passStoreChanged);
164 connect(pass, &Pass::finishedInit, this, &QtPass::passStoreChanged);
165 connect(pass, &Pass::finishedMove, this, &QtPass::passStoreChanged);
166 connect(pass, &Pass::finishedCopy, this, &QtPass::passStoreChanged);
167 connect(pass, &Pass::finishedGenerateGPGKeys, this,
168 &QtPass::onKeyGenerationComplete);
169}
170
174void QtPass::mountWebDav() {
175#ifdef Q_OS_WIN
176 char dst[20] = {0};
177 NETRESOURCEA netres;
178 memset(&netres, 0, sizeof(netres));
179 netres.dwType = RESOURCETYPE_DISK;
180 netres.lpLocalName = 0;
181 netres.lpRemoteName = QtPassSettings::getWebDavUrl().toUtf8().data();
182 DWORD size = sizeof(dst);
183 DWORD r = WNetUseConnectionA(
184 reinterpret_cast<HWND>(m_mainWindow->effectiveWinId()), &netres,
185 QtPassSettings::getWebDavPassword().toUtf8().constData(),
186 QtPassSettings::getWebDavUser().toUtf8().constData(),
187 CONNECT_TEMPORARY | CONNECT_INTERACTIVE | CONNECT_REDIRECT, dst, &size,
188 0);
189 if (r == NO_ERROR) {
190 QtPassSettings::setPassStore(dst);
191 } else {
192 char message[256] = {0};
193 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 0, r, 0, message,
194 sizeof(message), 0);
195 m_mainWindow->flashText(tr("Failed to connect WebDAV:\n") + message +
196 " (0x" + QString::number(r, 16) + ")",
197 true);
198 }
199#else
200 fusedav.start("fusedav", QStringList()
201 << "-o"
202 << "nonempty"
203 << "-u"
204 << "\"" + QtPassSettings::getWebDavUser() + "\""
205 << QtPassSettings::getWebDavUrl()
206 << "\"" + QtPassSettings::getPassStore() + "\"");
207 fusedav.waitForStarted();
208 if (fusedav.state() == QProcess::Running) {
209 QString pwd = QtPassSettings::getWebDavPassword();
210 bool ok = true;
211 if (pwd.isEmpty()) {
212 pwd = QInputDialog::getText(m_mainWindow, tr("QtPass WebDAV password"),
213 tr("Enter password to connect to WebDAV:"),
214 QLineEdit::Password, "", &ok);
215 }
216 if (ok && !pwd.isEmpty()) {
217 fusedav.write(pwd.toUtf8() + '\n');
218 fusedav.closeWriteChannel();
219 fusedav.waitForFinished(2000);
220 } else {
221 fusedav.terminate();
222 }
223 }
224 QString error = fusedav.readAllStandardError();
225 int prompt = error.indexOf("Password:");
226 if (prompt >= 0)
227 error.remove(0, prompt + 10);
228 if (fusedav.state() != QProcess::Running)
229 error = tr("fusedav exited unexpectedly\n") + error;
230 if (error.size() > 0) {
231 m_mainWindow->flashText(
232 tr("Failed to start fusedav to connect WebDAV:\n") + error, true);
233 }
234#endif
235}
236
241void QtPass::processError(QProcess::ProcessError error) {
242 QString errorString;
243 switch (error) {
244 case QProcess::FailedToStart:
245 errorString = tr("QProcess::FailedToStart");
246 break;
247 case QProcess::Crashed:
248 errorString = tr("QProcess::Crashed");
249 break;
250 case QProcess::Timedout:
251 errorString = tr("QProcess::Timedout");
252 break;
253 case QProcess::ReadError:
254 errorString = tr("QProcess::ReadError");
255 break;
256 case QProcess::WriteError:
257 errorString = tr("QProcess::WriteError");
258 break;
259 case QProcess::UnknownError:
260 errorString = tr("QProcess::UnknownError");
261 break;
262 }
263
264 m_mainWindow->flashText(errorString, true);
265 m_mainWindow->setUiElementsEnabled(true);
266}
267
268void QtPass::processErrorExit(int exitCode, const QString &p_error) {
269 if (!p_error.isEmpty()) {
270 QString output;
271 QString error = p_error.toHtmlEscaped();
272 if (exitCode == 0) {
273 // https://github.com/IJHack/qtpass/issues/111
274 output = "<span style=\"color: darkgray;\">" + error + "</span><br />";
275 } else {
276 output = "<span style=\"color: red;\">" + error + "</span><br />";
277 }
278
279 output.replace(Util::protocolRegex(), R"(<a href="1円">1円</a>)");
280 output.replace(QStringLiteral("\n"), "<br />");
281
282 m_mainWindow->flashText(output, false, true);
283 }
284
285 m_mainWindow->setUiElementsEnabled(true);
286}
287
295void QtPass::processFinished(const QString &p_output, const QString &p_errout) {
296 showInTextBrowser(p_output);
297 // Sometimes there is error output even with 0 exit code, which is
298 // assumed in this function
299 processErrorExit(0, p_errout);
300
301 m_mainWindow->setUiElementsEnabled(true);
302}
303
304void QtPass::passStoreChanged(const QString &p_out, const QString &p_err) {
305 processFinished(p_out, p_err);
306 doGitPush();
307}
308
309void QtPass::finishedInsert(const QString &p_output, const QString &p_errout) {
310 processFinished(p_output, p_errout);
311 doGitPush();
312 m_mainWindow->on_treeView_clicked(m_mainWindow->getCurrentTreeViewIndex());
313}
314
315void QtPass::onKeyGenerationComplete(const QString &p_output,
316 const QString &p_errout) {
317 if (nullptr != m_mainWindow->getKeygenDialog()) {
318#ifdef QT_DEBUG
319 qDebug() << "Keygen Done";
320#endif
321
322 m_mainWindow->cleanKeygenDialog();
323 // TODO(annejan) some sanity checking ?
324 }
325
326 processFinished(p_output, p_errout);
327}
328
329void QtPass::passShowHandlerFinished(QString output) {
330 showInTextBrowser(std::move(output));
331}
332
333void QtPass::showInTextBrowser(QString output, QString prefix,
334 QString postfix) {
335 output = output.toHtmlEscaped();
336
337 output.replace(Util::protocolRegex(), R"(<a href="1円">1円</a>)");
338 output.replace(QStringLiteral("\n"), "<br />");
339 output = prefix + output + postfix;
340
341 m_mainWindow->flashText(output, false, true);
342}
343
344void QtPass::doGitPush() {
345 if (QtPassSettings::isAutoPush())
346 m_mainWindow->onPush();
347}
348
349 void QtPass::setClippedText(const QString &password, const QString &p_output) {
350 if (QtPassSettings::getClipBoardType() != Enums::CLIPBOARD_NEVER &&
351 !p_output.isEmpty()) {
352 clippedText = password;
353 if (QtPassSettings::getClipBoardType() == Enums::CLIPBOARD_ALWAYS)
354 copyTextToClipboard(password);
355 }
356}
357 void QtPass::clearClippedText() { clippedText = ""; }
358
359 void QtPass::setClipboardTimer() {
360 clearClipboardTimer.setInterval(1000 * QtPassSettings::getAutoclearSeconds());
361}
362
366 void QtPass::clearClipboard() {
367 QClipboard *clipboard = QApplication::clipboard();
368 bool cleared = false;
369 if (this->clippedText == clipboard->text(QClipboard::Selection)) {
370 clipboard->clear(QClipboard::Selection);
371 clipboard->setText(QString(""), QClipboard::Selection);
372 cleared = true;
373 }
374 if (this->clippedText == clipboard->text(QClipboard::Clipboard)) {
375 clipboard->clear(QClipboard::Clipboard);
376 cleared = true;
377 }
378 if (cleared) {
379 m_mainWindow->showStatusMessage(tr("Clipboard cleared"));
380 } else {
381 m_mainWindow->showStatusMessage(tr("Clipboard not cleared"));
382 }
383
384 clippedText.clear();
385}
386
391 void QtPass::copyTextToClipboard(const QString &text) {
392 QClipboard *clip = QApplication::clipboard();
393 if (!QtPassSettings::isUseSelection()) {
394 clip->setText(text, QClipboard::Clipboard);
395 } else {
396 clip->setText(text, QClipboard::Selection);
397 }
398
399 clippedText = text;
400 m_mainWindow->showStatusMessage(tr("Copied to clipboard"));
401 if (QtPassSettings::isUseAutoclear()) {
402 clearClipboardTimer.start();
403 }
404}
405
410 void QtPass::showTextAsQRCode(const QString &text) {
411 QProcess qrencode;
412 qrencode.start(QtPassSettings::getQrencodeExecutable("/usr/bin/qrencode"),
413 QStringList() << "-o-"
414 << "-tPNG");
415 qrencode.write(text.toUtf8());
416 qrencode.closeWriteChannel();
417 qrencode.waitForFinished();
418 QByteArray output(qrencode.readAllStandardOutput());
419
420 if (qrencode.exitStatus() || qrencode.exitCode()) {
421 QString error(qrencode.readAllStandardError());
422 m_mainWindow->showStatusMessage(error);
423 } else {
424 QPixmap image;
425 image.loadFromData(output, "PNG");
426
427 QDialog *popup = new QDialog(0, Qt::Popup | Qt::FramelessWindowHint);
428 QVBoxLayout *layout = new QVBoxLayout;
429 QLabel *popupLabel = new QLabel();
430 layout->addWidget(popupLabel);
431 popupLabel->setPixmap(image);
432 popupLabel->setScaledContents(true);
433 popupLabel->show();
434 popup->setLayout(layout);
435 popup->move(QCursor::pos());
436 popup->exec();
437 }
438}
ImitatePass::endReencryptPath
void endReencryptPath()
ImitatePass::startReencryptPath
void startReencryptPath()
MainWindow
The MainWindow class does way too much, not only is it a switchboard, configuration handler and more,...
Definition: mainwindow.h:37
MainWindow::startReencryptPath
void startReencryptPath()
MainWindow::startReencryptPath disable ui elements and treeview.
Definition: mainwindow.cpp:1187
MainWindow::passShowHandler
void passShowHandler(const QString &)
Definition: mainwindow.cpp:383
MainWindow::endReencryptPath
void endReencryptPath()
MainWindow::endReencryptPath re-enable ui elements.
Definition: mainwindow.cpp:1195
MainWindow::executeWrapperStarted
void executeWrapperStarted()
Definition: mainwindow.cpp:376
MainWindow::showStatusMessage
void showStatusMessage(QString msg, int timeout=2000)
Displays message in status bar.
Definition: mainwindow.cpp:1180
MainWindow::passGitInitNeeded
void passGitInitNeeded()
MainWindow::onPush
void onPush()
MainWindow::onPush do a git push.
Definition: mainwindow.cpp:302
MainWindow::critical
void critical(QString, QString)
MainWindow::critical critical message popup wrapper.
Definition: mainwindow.cpp:1228
MainWindow::generateGPGKeyPair
void generateGPGKeyPair(QString batch)
MainWindow::passOtpHandler
void passOtpHandler(const QString &)
Definition: mainwindow.cpp:429
MainWindow::restoreWindow
void restoreWindow()
Definition: mainwindow.cpp:478
MainWindow::getKeygenDialog
QDialog * getKeygenDialog()
Definition: mainwindow.h:56
MainWindow::getCurrentTreeViewIndex
const QModelIndex getCurrentTreeViewIndex()
Definition: mainwindow.cpp:201
MainWindow::flashText
void flashText(const QString &text, const bool isError, const bool isHtml=false)
Definition: mainwindow.cpp:210
MainWindow::setUiElementsEnabled
void setUiElementsEnabled(bool state)
MainWindow::setUiElementsEnabled enable or disable the relevant UI elements.
Definition: mainwindow.cpp:462
MainWindow::cleanKeygenDialog
void cleanKeygenDialog()
Definition: mainwindow.cpp:205
MainWindow::on_treeView_clicked
void on_treeView_clicked(const QModelIndex &index)
MainWindow::on_treeView_clicked read the selected password file.
Definition: mainwindow.cpp:332
MainWindow::config
void config()
MainWindow::config pops up the configuration screen and handles all inter-window communication.
Definition: mainwindow.cpp:230
MainWindow::passShowHandlerFinished
void passShowHandlerFinished(QString output)
Pass
Acts as an abstraction for pass or pass imitation.
Definition: pass.h:18
Pass::startingExecuteWrapper
void startingExecuteWrapper()
Pass::GenerateGPGKeys
void GenerateGPGKeys(QString batch)
Pass::GenerateGPGKeys internal gpg keypair generator . .
Definition: pass.cpp:116
Pass::finishedCopy
void finishedCopy(const QString &, const QString &)
Pass::finishedShow
void finishedShow(const QString &)
Pass::finishedRemove
void finishedRemove(const QString &, const QString &)
Pass::GitInit
virtual void GitInit()=0
Pass::finishedMove
void finishedMove(const QString &, const QString &)
Pass::statusMsg
void statusMsg(QString, int)
Pass::critical
void critical(QString, QString)
Pass::finishedGitInit
void finishedGitInit(const QString &, const QString &)
Pass::finishedInsert
void finishedInsert(const QString &, const QString &)
Pass::finishedInit
void finishedInit(const QString &, const QString &)
Pass::finishedOtpGenerate
void finishedOtpGenerate(const QString &)
Pass::processErrorExit
void processErrorExit(int exitCode, const QString &err)
Pass::finishedGitPull
void finishedGitPull(const QString &, const QString &)
Pass::finishedGitPush
void finishedGitPush(const QString &, const QString &)
Pass::error
void error(QProcess::ProcessError)
Pass::finishedGenerateGPGKeys
void finishedGenerateGPGKeys(const QString &, const QString &)
QtPass::clearClippedText
void clearClippedText()
Definition: qtpass.cpp:357
QtPass::setClipboardTimer
void setClipboardTimer()
Definition: qtpass.cpp:359
QtPass::clearClipboard
void clearClipboard()
MainWindow::clearClipboard remove clipboard contents.
Definition: qtpass.cpp:366
QtPass::init
bool init()
QtPass::init make sure we are ready to go as soon as possible.
Definition: qtpass.cpp:61
QtPass::~QtPass
~QtPass()
QtPass::~QtPass destroy!
Definition: qtpass.cpp:44
QtPass::setClippedText
void setClippedText(const QString &, const QString &p_output=QString())
Definition: qtpass.cpp:349
QtPass::QtPass
QtPass(MainWindow *mainWindow)
Definition: qtpass.cpp:28
QtPass::copyTextToClipboard
void copyTextToClipboard(const QString &text)
MainWindow::copyTextToClipboard copies text to your clipboard.
Definition: qtpass.cpp:391
QtPass::showTextAsQRCode
void showTextAsQRCode(const QString &text)
displays the text as qrcode
Definition: qtpass.cpp:410
QtPassSettings::getVersion
static QString getVersion(const QString &defaultValue=QVariant().toString())
Definition: qtpasssettings.cpp:119
QtPassSettings::setAutoclearPanelSeconds
static void setAutoclearPanelSeconds(const int &autoClearPanelSeconds)
Definition: qtpasssettings.cpp:241
QtPassSettings::getWebDavUrl
static QString getWebDavUrl(const QString &defaultValue=QVariant().toString())
Definition: qtpasssettings.cpp:403
QtPassSettings::getAutoclearPanelSeconds
static int getAutoclearPanelSeconds(const int &defaultValue=QVariant().toInt())
Definition: qtpasssettings.cpp:236
QtPassSettings::setPassStore
static void setPassStore(const QString &passStore)
Definition: qtpasssettings.cpp:322
QtPassSettings::getImitatePass
static ImitatePass * getImitatePass()
Definition: qtpasssettings.cpp:618
QtPassSettings::getPassTemplate
static QString getPassTemplate(const QString &defaultValue=QVariant().toString())
Definition: qtpasssettings.cpp:585
QtPassSettings::getAutoclearSeconds
static int getAutoclearSeconds(const int &defaultValue=QVariant().toInt())
Definition: qtpasssettings.cpp:216
QtPassSettings::setUsePwgen
static void setUsePwgen(const bool &usePwgen)
Definition: qtpasssettings.cpp:479
QtPassSettings::getPwgenExecutable
static QString getPwgenExecutable(const QString &defaultValue=QVariant().toString())
Definition: qtpasssettings.cpp:379
QtPassSettings::getWebDavUser
static QString getWebDavUser(const QString &defaultValue=QVariant().toString())
Definition: qtpasssettings.cpp:412
QtPassSettings::initExecutables
static void initExecutables()
Definition: qtpasssettings.cpp:335
QtPassSettings::isUseWebDav
static bool isUseWebDav(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:394
QtPassSettings::setPassTemplate
static void setPassTemplate(const QString &passTemplate)
Definition: qtpasssettings.cpp:590
QtPassSettings::setVersion
static void setVersion(const QString &version)
Definition: qtpasssettings.cpp:124
QtPassSettings::getPass
static Pass * getPass()
Definition: qtpasssettings.cpp:107
QtPassSettings::getClipBoardType
static Enums::clipBoardType getClipBoardType(const Enums::clipBoardType &defaultvalue=Enums::CLIPBOARD_NEVER)
Definition: qtpasssettings.cpp:191
QtPassSettings::getRealPass
static RealPass * getRealPass()
Definition: qtpasssettings.cpp:613
QtPassSettings::isAutoPush
static bool isAutoPush(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:576
QtPassSettings::getPassStore
static QString getPassStore(const QString &defaultValue=QVariant().toString())
Definition: qtpasssettings.cpp:301
QtPassSettings::setAutoclearSeconds
static void setAutoclearSeconds(const int &autoClearSeconds)
Definition: qtpasssettings.cpp:221
QtPassSettings::getQrencodeExecutable
static QString getQrencodeExecutable(const QString &defaultValue=QVariant().toString())
Definition: qtpasssettings.cpp:464
QtPassSettings::isUseAutoclear
static bool isUseAutoclear(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:207
QtPassSettings::getWebDavPassword
static QString getWebDavPassword(const QString &defaultValue=QVariant().toString())
Definition: qtpasssettings.cpp:421
QtPassSettings::isUseSelection
static bool isUseSelection(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:198
Util::checkConfig
static bool checkConfig()
Util::checkConfig do we have prequisite settings?
Definition: util.cpp:142
Util::findPasswordStore
static QString findPasswordStore()
Util::findPasswordStore look for common .password-store folder location.
Definition: util.cpp:56
Util::protocolRegex
static const QRegularExpression & protocolRegex()
Definition: util.cpp:203
dbg
#define dbg()
Definition: debughelper.h:7
Enums::CLIPBOARD_ALWAYS
@ CLIPBOARD_ALWAYS
Definition: enums.h:12
Enums::CLIPBOARD_NEVER
@ CLIPBOARD_NEVER
Definition: enums.h:11

Generated by doxygen 1.9.6

AltStyle によって変換されたページ (->オリジナル) /