Confronta commit
	
		
			15 Commit
		
	
	
		
			v0.2
			...
			11decb757f
		
	
	| Autore | SHA1 | Data | |
|---|---|---|---|
| 11decb757f | |||
| b71c234fb4 | |||
| bc908a1038 | |||
| 8ba4ee5847 | |||
| 451c79088a | |||
| 1a39118470 | |||
| 0d2e518000 | |||
| b108cb7151 | |||
| c82cf03814 | |||
| 8a82da95bd | |||
| a408173064 | |||
| dd479fa668 | |||
| e76988ee77 | |||
| f29f997289 | |||
| afa9d33f3d | 
							
								
								
									
										33
									
								
								gui/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								gui/main.cpp
									
									
									
									
									
								
							| @@ -26,8 +26,7 @@ void enableIpcSandbox() | |||||||
| 	policy->namespace_options = EXILE_UNSHARE_USER | EXILE_UNSHARE_MOUNT | EXILE_UNSHARE_NETWORK; | 	policy->namespace_options = EXILE_UNSHARE_USER | EXILE_UNSHARE_MOUNT | EXILE_UNSHARE_NETWORK; | ||||||
| 	policy->no_new_privs = 1; | 	policy->no_new_privs = 1; | ||||||
| 	policy->drop_caps = 1; | 	policy->drop_caps = 1; | ||||||
| 	policy->vow_promises = | 	policy->vow_promises = exile_vows_from_str("thread cpath rpath unix stdio proc error"); | ||||||
| 		exile_vows_from_str("thread cpath wpath rpath unix stdio prot_exec proc shm fsnotify ioctl error"); |  | ||||||
| 	policy->mount_path_policies_to_chroot = 1; | 	policy->mount_path_policies_to_chroot = 1; | ||||||
|  |  | ||||||
| 	QString ipcSocketPath = Common::ipcSocketPath(); | 	QString ipcSocketPath = Common::ipcSocketPath(); | ||||||
| @@ -35,6 +34,12 @@ void enableIpcSandbox() | |||||||
| 	QString ipcSocketPathDir = info.absolutePath(); | 	QString ipcSocketPathDir = info.absolutePath(); | ||||||
| 	std::string stdIpcSocketPath = ipcSocketPathDir.toStdString(); | 	std::string stdIpcSocketPath = ipcSocketPathDir.toStdString(); | ||||||
|  |  | ||||||
|  | 	/* we only need the 'server' side of the 'unix' vow (for unix sockets)'. The process | ||||||
|  | 	 * has no business to connect anywhere. | ||||||
|  | 	 * | ||||||
|  | 	 * Maybe this case should be handled by exile at some point, but for now deal with it here */ | ||||||
|  | 	exile_append_syscall_policy(policy, EXILE_SYS(connect), EXILE_SYSCALL_DENY_RET_ERROR, NULL, 0); | ||||||
|  |  | ||||||
| 	/* ALLOW_EXEC is needed for fallback, not in landlock mode. It does not allow executing anything though here | 	/* ALLOW_EXEC is needed for fallback, not in landlock mode. It does not allow executing anything though here | ||||||
| 	 * due to the vows */ | 	 * due to the vows */ | ||||||
| 	exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ | EXILE_FS_ALLOW_EXEC, "/"); | 	exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ | EXILE_FS_ALLOW_EXEC, "/"); | ||||||
| @@ -43,9 +48,26 @@ void enableIpcSandbox() | |||||||
| 	int ret = exile_enable_policy(policy); | 	int ret = exile_enable_policy(policy); | ||||||
| 	if(ret != 0) | 	if(ret != 0) | ||||||
| 	{ | 	{ | ||||||
| 		qDebug() << "Failed to establish sandbox"; | 		qDebug() << "Failed to establish sandbox" << Qt::endl; | ||||||
| 		exit(EXIT_FAILURE); | 		exit(EXIT_FAILURE); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/* Arguments are irrelevant for sandbox test, just want to silence analyzer/compiler warnings */ | ||||||
|  | 	ret = socket(AF_INET, SOCK_STREAM, 0); | ||||||
|  | 	if(ret != -1 || errno != EACCES) | ||||||
|  | 	{ | ||||||
|  | 		qCritical() << "Sandbox sanity check failed" << Qt::endl; | ||||||
|  | 		exit(EXIT_FAILURE); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	const struct sockaddr *addr = {}; | ||||||
|  | 	ret = connect(3, addr, sizeof(*addr)); | ||||||
|  | 	if(ret != -1 || errno != EACCES) | ||||||
|  | 	{ | ||||||
|  | 		qCritical() << "Sandbox sanity check failed" << Qt::endl; | ||||||
|  | 		exit(EXIT_FAILURE); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	exile_free_policy(policy); | 	exile_free_policy(policy); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -66,7 +88,7 @@ int main(int argc, char *argv[]) | |||||||
| 			{ | 			{ | ||||||
| 				enableIpcSandbox(); | 				enableIpcSandbox(); | ||||||
| 			} | 			} | ||||||
| 			QApplication a(argc, argv); | 			QCoreApplication a(argc, argv); | ||||||
|  |  | ||||||
| 			IpcServer *ipcserver = new IpcServer(); | 			IpcServer *ipcserver = new IpcServer(); | ||||||
| 			qDebug() << "Launching IPC Server"; | 			qDebug() << "Launching IPC Server"; | ||||||
| @@ -120,7 +142,6 @@ int main(int argc, char *argv[]) | |||||||
| 	} | 	} | ||||||
| 	Common::setupAppInfo(); | 	Common::setupAppInfo(); | ||||||
| 	QCommandLineParser parser; | 	QCommandLineParser parser; | ||||||
| 	parser.addOption({{"s", "no-sandbox"}, "Disable sandboxing"}); |  | ||||||
| 	QStringList appArgs; | 	QStringList appArgs; | ||||||
| 	for(int i = 0; i < argc; i++) | 	for(int i = 0; i < argc; i++) | ||||||
| 	{ | 	{ | ||||||
| @@ -128,6 +149,7 @@ int main(int argc, char *argv[]) | |||||||
| 	} | 	} | ||||||
| 	parser.parse(appArgs); | 	parser.parse(appArgs); | ||||||
|  |  | ||||||
|  | 	QApplication a(argc, argv); | ||||||
| 	try | 	try | ||||||
| 	{ | 	{ | ||||||
| 		Common::ensureConfigured(); | 		Common::ensureConfigured(); | ||||||
| @@ -138,7 +160,6 @@ int main(int argc, char *argv[]) | |||||||
| 		QMessageBox::critical(nullptr, "Error", e.message); | 		QMessageBox::critical(nullptr, "Error", e.message); | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
| 	QApplication a(argc, argv); |  | ||||||
| 	a.setWindowIcon(QIcon(":/looqs.svg")); | 	a.setWindowIcon(QIcon(":/looqs.svg")); | ||||||
| 	QObject::connect(&a, &QApplication::aboutToQuit, &process, &QProcess::kill); | 	QObject::connect(&a, &QApplication::aboutToQuit, &process, &QProcess::kill); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -192,12 +192,6 @@ void MainWindow::connectSignals() | |||||||
|  |  | ||||||
| 			QMessageBox::about(this, "About looqs", html); | 			QMessageBox::about(this, "About looqs", html); | ||||||
| 		}); | 		}); | ||||||
| 	connect(ui->menuOpenConfigInTextEditorAction, &QAction::triggered, this, |  | ||||||
| 			[this](bool checked) |  | ||||||
| 			{ |  | ||||||
| 				QSettings setting; |  | ||||||
| 				QDesktopServices::openUrl(setting.fileName()); |  | ||||||
| 			}); |  | ||||||
| 	connect(ui->menuAboutQtAction, &QAction::triggered, this, | 	connect(ui->menuAboutQtAction, &QAction::triggered, this, | ||||||
| 			[this](bool checked) { QMessageBox::aboutQt(this, "About Qt"); }); | 			[this](bool checked) { QMessageBox::aboutQt(this, "About Qt"); }); | ||||||
| 	connect(ui->menuSyncIndexAction, &QAction::triggered, this, &MainWindow::startIndexSync); | 	connect(ui->menuSyncIndexAction, &QAction::triggered, this, &MainWindow::startIndexSync); | ||||||
| @@ -215,6 +209,7 @@ void MainWindow::connectSignals() | |||||||
| 			}); | 			}); | ||||||
| 	connect(this, &MainWindow::beginIndexSync, indexSyncer, &IndexSyncer::sync); | 	connect(this, &MainWindow::beginIndexSync, indexSyncer, &IndexSyncer::sync); | ||||||
| 	connect(&this->progressDialog, &QProgressDialog::canceled, indexSyncer, &IndexSyncer::cancel); | 	connect(&this->progressDialog, &QProgressDialog::canceled, indexSyncer, &IndexSyncer::cancel); | ||||||
|  | 	connect(ui->btnSaveSettings, &QPushButton::clicked, this, &MainWindow::saveSettings); | ||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::startIndexSync() | void MainWindow::startIndexSync() | ||||||
| @@ -236,6 +231,7 @@ void MainWindow::startIndexSync() | |||||||
|  |  | ||||||
| 	emit beginIndexSync(); | 	emit beginIndexSync(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::spinPreviewPageValueChanged(int val) | void MainWindow::spinPreviewPageValueChanged(int val) | ||||||
| { | { | ||||||
| 	makePreviews(val); | 	makePreviews(val); | ||||||
| @@ -253,6 +249,7 @@ void MainWindow::startIndexing() | |||||||
|  |  | ||||||
| 	ui->previewsTab->setEnabled(false); | 	ui->previewsTab->setEnabled(false); | ||||||
| 	ui->resultsTab->setEnabled(false); | 	ui->resultsTab->setEnabled(false); | ||||||
|  | 	ui->settingsTab->setEnabled(false); | ||||||
| 	ui->txtPathScanAdd->setEnabled(false); | 	ui->txtPathScanAdd->setEnabled(false); | ||||||
| 	ui->txtSearch->setEnabled(false); | 	ui->txtSearch->setEnabled(false); | ||||||
| 	ui->previewProcessBar->setValue(0); | 	ui->previewProcessBar->setValue(0); | ||||||
| @@ -289,6 +286,7 @@ void MainWindow::finishIndexing() | |||||||
| 	ui->btnStartIndexing->setText("Start indexing"); | 	ui->btnStartIndexing->setText("Start indexing"); | ||||||
| 	ui->previewsTab->setEnabled(true); | 	ui->previewsTab->setEnabled(true); | ||||||
| 	ui->resultsTab->setEnabled(true); | 	ui->resultsTab->setEnabled(true); | ||||||
|  | 	ui->settingsTab->setEnabled(true); | ||||||
| 	ui->txtPathScanAdd->setEnabled(true); | 	ui->txtPathScanAdd->setEnabled(true); | ||||||
| 	ui->txtSearch->setEnabled(true); | 	ui->txtSearch->setEnabled(true); | ||||||
| } | } | ||||||
| @@ -351,6 +349,49 @@ void MainWindow::tabChanged() | |||||||
| 			makePreviews(ui->spinPreviewPage->value()); | 			makePreviews(ui->spinPreviewPage->value()); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	/* Settings tab active */ | ||||||
|  | 	if(ui->tabWidget->currentIndex() == 3) | ||||||
|  | 	{ | ||||||
|  | 		initSettingsTabs(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void MainWindow::initSettingsTabs() | ||||||
|  | { | ||||||
|  | 	QSettings settings; | ||||||
|  |  | ||||||
|  | 	QString pdfViewerCmd = settings.value(SETTINGS_KEY_PDFVIEWER).toString(); | ||||||
|  | 	QString excludedPaths = Common::excludedPaths().join(';'); | ||||||
|  | 	QString mountPaths = Common::mountPaths().join(';'); | ||||||
|  | 	QString databasePath = Common::databasePath(); | ||||||
|  | 	int numPagesPerPreview = settings.value(SETTINGS_KEY_PREVIEWSPERPAGE, 20).toInt(); | ||||||
|  |  | ||||||
|  | 	ui->txtSettingPdfPreviewerCmd->setText(pdfViewerCmd); | ||||||
|  | 	ui->txtSettingIgnoredPaths->setText(excludedPaths); | ||||||
|  | 	ui->txtSettingMountPaths->setText(mountPaths); | ||||||
|  | 	ui->spinSettingNumerPerPages->setValue(numPagesPerPreview); | ||||||
|  | 	ui->txtSettingDatabasePath->setText(databasePath); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void MainWindow::saveSettings() | ||||||
|  | { | ||||||
|  | 	QSettings settings; | ||||||
|  |  | ||||||
|  | 	QString pdfViewerCmd = ui->txtSettingPdfPreviewerCmd->text(); | ||||||
|  | 	QStringList excludedPaths = ui->txtSettingIgnoredPaths->text().split(';'); | ||||||
|  | 	QStringList mountPaths = ui->txtSettingMountPaths->text().split(';'); | ||||||
|  | 	QString databasePath = ui->txtSettingDatabasePath->text(); | ||||||
|  |  | ||||||
|  | 	settings.setValue(SETTINGS_KEY_PDFVIEWER, pdfViewerCmd); | ||||||
|  | 	settings.setValue(SETTINGS_KEY_EXCLUDEDPATHS, excludedPaths); | ||||||
|  | 	settings.setValue(SETTINGS_KEY_MOUNTPATHS, mountPaths); | ||||||
|  | 	settings.setValue(SETTINGS_KEY_PREVIEWSPERPAGE, ui->spinSettingNumerPerPages->value()); | ||||||
|  | 	settings.setValue(SETTINGS_KEY_DBPATH, databasePath); | ||||||
|  |  | ||||||
|  | 	settings.sync(); | ||||||
|  |  | ||||||
|  | 	QProcess::startDetached(qApp->arguments()[0], qApp->arguments().mid(1)); | ||||||
|  | 	qApp->quit(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::previewReceived(QSharedPointer<PreviewResult> preview, unsigned int previewGeneration) | void MainWindow::previewReceived(QSharedPointer<PreviewResult> preview, unsigned int previewGeneration) | ||||||
| @@ -389,7 +430,7 @@ void MainWindow::lineEditReturnPressed() | |||||||
| 		ui->lblSearchResults->setText("Invalid paranthesis"); | 		ui->lblSearchResults->setText("Invalid paranthesis"); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	if(indexerTabActive()) | 	if(ui->tabWidget->currentIndex() > 1) | ||||||
| 	{ | 	{ | ||||||
| 		ui->tabWidget->setCurrentIndex(0); | 		ui->tabWidget->setCurrentIndex(0); | ||||||
| 	} | 	} | ||||||
| @@ -454,6 +495,11 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results) | |||||||
| 		bool exists = pathInfo.exists(); | 		bool exists = pathInfo.exists(); | ||||||
| 		if(exists) | 		if(exists) | ||||||
| 		{ | 		{ | ||||||
|  | 			if(!result.wasContentSearch) | ||||||
|  | 			{ | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 			if(!pathInfo.suffix().contains("htm")) // hack until we can preview them properly... | 			if(!pathInfo.suffix().contains("htm")) // hack until we can preview them properly... | ||||||
| 			{ | 			{ | ||||||
| 				if(PreviewGenerator::get(pathInfo) != nullptr) | 				if(PreviewGenerator::get(pathInfo) != nullptr) | ||||||
| @@ -502,7 +548,7 @@ void MainWindow::makePreviews(int page) | |||||||
| 	scaleText.chop(1); | 	scaleText.chop(1); | ||||||
|  |  | ||||||
| 	QVector<QString> wordsToHighlight; | 	QVector<QString> wordsToHighlight; | ||||||
| 	QRegularExpression extractor(R"#("([^"]*)"|(\p{L}+))#"); | 	QRegularExpression extractor(R"#("([^"]*)"|((\p{L}|\p{N})+))#"); | ||||||
| 	for(const Token &token : this->contentSearchQuery.getTokens()) | 	for(const Token &token : this->contentSearchQuery.getTokens()) | ||||||
| 	{ | 	{ | ||||||
| 		if(token.type == FILTER_CONTENT_CONTAINS) | 		if(token.type == FILTER_CONTENT_CONTAINS) | ||||||
|   | |||||||
| @@ -61,6 +61,7 @@ class MainWindow : public QMainWindow | |||||||
| 	void openDocument(QString path, int num); | 	void openDocument(QString path, int num); | ||||||
| 	void openFile(QString path); | 	void openFile(QString path); | ||||||
| 	unsigned int currentPreviewGeneration = 1; | 	unsigned int currentPreviewGeneration = 1; | ||||||
|  | 	void initSettingsTabs(); | ||||||
|   private slots: |   private slots: | ||||||
| 	void lineEditReturnPressed(); | 	void lineEditReturnPressed(); | ||||||
| 	void treeSearchItemActivated(QTreeWidgetItem *item, int i); | 	void treeSearchItemActivated(QTreeWidgetItem *item, int i); | ||||||
| @@ -73,6 +74,7 @@ class MainWindow : public QMainWindow | |||||||
| 	void finishIndexing(); | 	void finishIndexing(); | ||||||
| 	void addPathToIndex(); | 	void addPathToIndex(); | ||||||
| 	void startIndexSync(); | 	void startIndexSync(); | ||||||
|  | 	void saveSettings(); | ||||||
|  |  | ||||||
|   signals: |   signals: | ||||||
| 	void startIpcPreviews(RenderConfig config, const QVector<RenderTarget> &targets); | 	void startIpcPreviews(RenderConfig config, const QVector<RenderTarget> &targets); | ||||||
|   | |||||||
| @@ -6,8 +6,8 @@ | |||||||
|    <rect> |    <rect> | ||||||
|     <x>0</x> |     <x>0</x> | ||||||
|     <y>0</y> |     <y>0</y> | ||||||
|     <width>1221</width> |     <width>1280</width> | ||||||
|     <height>709</height> |     <height>736</height> | ||||||
|    </rect> |    </rect> | ||||||
|   </property> |   </property> | ||||||
|   <property name="windowTitle"> |   <property name="windowTitle"> | ||||||
| @@ -27,7 +27,7 @@ | |||||||
|        <enum>QTabWidget::South</enum> |        <enum>QTabWidget::South</enum> | ||||||
|       </property> |       </property> | ||||||
|       <property name="currentIndex"> |       <property name="currentIndex"> | ||||||
|        <number>0</number> |        <number>3</number> | ||||||
|       </property> |       </property> | ||||||
|       <widget class="QWidget" name="resultsTab"> |       <widget class="QWidget" name="resultsTab"> | ||||||
|        <attribute name="title"> |        <attribute name="title"> | ||||||
| @@ -81,8 +81,8 @@ | |||||||
|             <rect> |             <rect> | ||||||
|              <x>0</x> |              <x>0</x> | ||||||
|              <y>0</y> |              <y>0</y> | ||||||
|              <width>1185</width> |              <width>1244</width> | ||||||
|              <height>419</height> |              <height>446</height> | ||||||
|             </rect> |             </rect> | ||||||
|            </property> |            </property> | ||||||
|            <layout class="QHBoxLayout" name="horizontalLayout"/> |            <layout class="QHBoxLayout" name="horizontalLayout"/> | ||||||
| @@ -344,6 +344,145 @@ | |||||||
|         </item> |         </item> | ||||||
|        </layout> |        </layout> | ||||||
|       </widget> |       </widget> | ||||||
|  |       <widget class="QWidget" name="settingsTab"> | ||||||
|  |        <attribute name="title"> | ||||||
|  |         <string>Settings</string> | ||||||
|  |        </attribute> | ||||||
|  |        <layout class="QVBoxLayout" name="verticalLayout_6"> | ||||||
|  |         <item> | ||||||
|  |          <widget class="QGroupBox" name="groupPdfSettings"> | ||||||
|  |           <property name="title"> | ||||||
|  |            <string>PDF Viewer</string> | ||||||
|  |           </property> | ||||||
|  |           <layout class="QVBoxLayout" name="verticalLayout_5"> | ||||||
|  |            <item> | ||||||
|  |             <widget class="QLabel" name="label_2"> | ||||||
|  |              <property name="text"> | ||||||
|  |               <string>Command to open PDF pages in (%f = file path; %p = page number)</string> | ||||||
|  |              </property> | ||||||
|  |             </widget> | ||||||
|  |            </item> | ||||||
|  |            <item> | ||||||
|  |             <widget class="QLineEdit" name="txtSettingPdfPreviewerCmd"/> | ||||||
|  |            </item> | ||||||
|  |           </layout> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item> | ||||||
|  |          <widget class="QGroupBox" name="groupMountPaths"> | ||||||
|  |           <property name="title"> | ||||||
|  |            <string>Mount paths</string> | ||||||
|  |           </property> | ||||||
|  |           <layout class="QVBoxLayout" name="verticalLayout_7"> | ||||||
|  |            <item> | ||||||
|  |             <widget class="QLabel" name="lblMountPaths"> | ||||||
|  |              <property name="text"> | ||||||
|  |               <string>Path prefixes of files that should not be removed during sync, even if they cannot be accessed (e . g. files indexed on external disks) . Separated by ;</string> | ||||||
|  |              </property> | ||||||
|  |             </widget> | ||||||
|  |            </item> | ||||||
|  |            <item> | ||||||
|  |             <widget class="QLineEdit" name="txtSettingMountPaths"/> | ||||||
|  |            </item> | ||||||
|  |           </layout> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item> | ||||||
|  |          <widget class="QGroupBox" name="groupBox"> | ||||||
|  |           <property name="title"> | ||||||
|  |            <string>Ignored paths</string> | ||||||
|  |           </property> | ||||||
|  |           <layout class="QVBoxLayout" name="verticalLayout_8"> | ||||||
|  |            <item> | ||||||
|  |             <widget class="QLabel" name="label_3"> | ||||||
|  |              <property name="text"> | ||||||
|  |               <string>Path prefixes that should always be ignored during indexing (will be applied before the ignore patterns). Separated by ;</string> | ||||||
|  |              </property> | ||||||
|  |             </widget> | ||||||
|  |            </item> | ||||||
|  |            <item> | ||||||
|  |             <widget class="QLineEdit" name="txtSettingIgnoredPaths"/> | ||||||
|  |            </item> | ||||||
|  |           </layout> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item> | ||||||
|  |          <widget class="QGroupBox" name="groupSettingDatabasePath"> | ||||||
|  |           <property name="title"> | ||||||
|  |            <string>Database path</string> | ||||||
|  |           </property> | ||||||
|  |           <layout class="QVBoxLayout" name="verticalLayout_10"> | ||||||
|  |            <item> | ||||||
|  |             <widget class="QLabel" name="lblSettingDatabasePath"> | ||||||
|  |              <property name="text"> | ||||||
|  |               <string>Path of the database. Note: Changing it here will create an empty, new database. The old will not be moved.  </string> | ||||||
|  |              </property> | ||||||
|  |             </widget> | ||||||
|  |            </item> | ||||||
|  |            <item> | ||||||
|  |             <widget class="QLineEdit" name="txtSettingDatabasePath"/> | ||||||
|  |            </item> | ||||||
|  |           </layout> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item> | ||||||
|  |          <widget class="QGroupBox" name="Misc"> | ||||||
|  |           <property name="title"> | ||||||
|  |            <string>Misc</string> | ||||||
|  |           </property> | ||||||
|  |           <layout class="QVBoxLayout" name="verticalLayout_9"> | ||||||
|  |            <item> | ||||||
|  |             <layout class="QHBoxLayout" name="horizontalLayout_9"> | ||||||
|  |              <item> | ||||||
|  |               <widget class="QLabel" name="label_4"> | ||||||
|  |                <property name="text"> | ||||||
|  |                 <string>Max number of previews per 'page' in 'Previews' tab: </string> | ||||||
|  |                </property> | ||||||
|  |               </widget> | ||||||
|  |              </item> | ||||||
|  |              <item> | ||||||
|  |               <widget class="QSpinBox" name="spinSettingNumerPerPages"/> | ||||||
|  |              </item> | ||||||
|  |              <item> | ||||||
|  |               <spacer name="horizontalSpacer_2"> | ||||||
|  |                <property name="orientation"> | ||||||
|  |                 <enum>Qt::Horizontal</enum> | ||||||
|  |                </property> | ||||||
|  |                <property name="sizeHint" stdset="0"> | ||||||
|  |                 <size> | ||||||
|  |                  <width>40</width> | ||||||
|  |                  <height>20</height> | ||||||
|  |                 </size> | ||||||
|  |                </property> | ||||||
|  |               </spacer> | ||||||
|  |              </item> | ||||||
|  |             </layout> | ||||||
|  |            </item> | ||||||
|  |           </layout> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item> | ||||||
|  |          <spacer name="verticalSpacer"> | ||||||
|  |           <property name="orientation"> | ||||||
|  |            <enum>Qt::Vertical</enum> | ||||||
|  |           </property> | ||||||
|  |           <property name="sizeHint" stdset="0"> | ||||||
|  |            <size> | ||||||
|  |             <width>20</width> | ||||||
|  |             <height>40</height> | ||||||
|  |            </size> | ||||||
|  |           </property> | ||||||
|  |          </spacer> | ||||||
|  |         </item> | ||||||
|  |         <item> | ||||||
|  |          <widget class="QPushButton" name="btnSaveSettings"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Save settings and restart</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |        </layout> | ||||||
|  |       </widget> | ||||||
|      </widget> |      </widget> | ||||||
|     </item> |     </item> | ||||||
|     <item> |     <item> | ||||||
| @@ -368,7 +507,7 @@ | |||||||
|     <rect> |     <rect> | ||||||
|      <x>0</x> |      <x>0</x> | ||||||
|      <y>0</y> |      <y>0</y> | ||||||
|      <width>1221</width> |      <width>1280</width> | ||||||
|      <height>35</height> |      <height>35</height> | ||||||
|     </rect> |     </rect> | ||||||
|    </property> |    </property> | ||||||
| @@ -376,7 +515,6 @@ | |||||||
|     <property name="title"> |     <property name="title"> | ||||||
|      <string>looqs</string> |      <string>looqs</string> | ||||||
|     </property> |     </property> | ||||||
|     <addaction name="menuOpenConfigInTextEditorAction"/> |  | ||||||
|     <addaction name="menuSyncIndexAction"/> |     <addaction name="menuSyncIndexAction"/> | ||||||
|     <addaction name="menuAboutAction"/> |     <addaction name="menuAboutAction"/> | ||||||
|     <addaction name="menuAboutQtAction"/> |     <addaction name="menuAboutQtAction"/> | ||||||
| @@ -389,11 +527,6 @@ | |||||||
|     <string>About</string> |     <string>About</string> | ||||||
|    </property> |    </property> | ||||||
|   </action> |   </action> | ||||||
|   <action name="menuOpenConfigInTextEditorAction"> |  | ||||||
|    <property name="text"> |  | ||||||
|     <string>Open config in text editor</string> |  | ||||||
|    </property> |  | ||||||
|   </action> |  | ||||||
|   <action name="menuAboutQtAction"> |   <action name="menuAboutQtAction"> | ||||||
|    <property name="text"> |    <property name="text"> | ||||||
|     <string>About Qt</string> |     <string>About Qt</string> | ||||||
|   | |||||||
| @@ -14,13 +14,6 @@ | |||||||
| #include "databasefactory.h" | #include "databasefactory.h" | ||||||
| #include "logger.h" | #include "logger.h" | ||||||
|  |  | ||||||
| #define SETTINGS_KEY_DBPATH "dbpath" |  | ||||||
| #define SETTINGS_KEY_FIRSTRUN "firstrun" |  | ||||||
| #define SETTINGS_KEY_IPCSOCKETPATH "ipcsocketpath" |  | ||||||
| #define SETTINGS_KEY_PDFVIEWER "pdfviewer" |  | ||||||
| #define SETTINGS_KEY_EXCLUDEDPATHS "excludedpaths" |  | ||||||
| #define SETTINGS_KEY_MOUNTPATHS "mountpaths" |  | ||||||
|  |  | ||||||
| inline void initResources() | inline void initResources() | ||||||
| { | { | ||||||
| 	Q_INIT_RESOURCE(migrations); | 	Q_INIT_RESOURCE(migrations); | ||||||
| @@ -91,10 +84,10 @@ void Common::setPdfViewer() | |||||||
| void Common::ensureConfigured() | void Common::ensureConfigured() | ||||||
| { | { | ||||||
| 	QSettings settings; | 	QSettings settings; | ||||||
| 	QVariant firstRun = settings.value(SETTINGS_KEY_FIRSTRUN); | 	QString dbpath = databasePath(); | ||||||
| 	if(!firstRun.isValid()) | 	if(dbpath == "") | ||||||
| 	{ | 	{ | ||||||
| 		QString dbpath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); | 		dbpath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); | ||||||
| 		QDir dir; | 		QDir dir; | ||||||
| 		if(!dir.exists(dbpath)) | 		if(!dir.exists(dbpath)) | ||||||
| 		{ | 		{ | ||||||
| @@ -104,38 +97,34 @@ void Common::ensureConfigured() | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		dbpath += "/looqs.sqlite"; | 		dbpath += "/looqs.sqlite"; | ||||||
|  | 	} | ||||||
|  | 	if(!QFile::exists(dbpath)) | ||||||
|  | 	{ | ||||||
| 		if(!initSqliteDatabase(dbpath)) | 		if(!initSqliteDatabase(dbpath)) | ||||||
| 		{ | 		{ | ||||||
| 			throw LooqsGeneralException("Failed to initialize sqlite database"); | 			throw LooqsGeneralException("Failed to initialize sqlite database"); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		settings.setValue(SETTINGS_KEY_FIRSTRUN, false); |  | ||||||
| 		settings.setValue(SETTINGS_KEY_DBPATH, dbpath); | 		settings.setValue(SETTINGS_KEY_DBPATH, dbpath); | ||||||
| 		setPdfViewer(); |  | ||||||
| 	} | 	} | ||||||
| 	else | 	DatabaseFactory factory{dbpath}; | ||||||
|  | 	auto db = factory.forCurrentThread(); | ||||||
|  | 	DBMigrator migrator{db}; | ||||||
|  | 	if(migrator.migrationNeeded()) | ||||||
| 	{ | 	{ | ||||||
|  | 		QFile out; | ||||||
| 		QString dbpath = databasePath(); | 		out.open(stderr, QIODevice::WriteOnly); | ||||||
| 		if(!QFile::exists(dbpath)) | 		Logger migrationLogger{&out}; | ||||||
| 		{ | 		migrationLogger << "Database is being upgraded, please be patient..." << Qt::endl; | ||||||
| 			throw LooqsGeneralException("Database " + dbpath + " was not found"); | 		QObject::connect(&migrator, &DBMigrator::migrationDone, | ||||||
| 		} | 						 [&migrationLogger](uint32_t migration) | ||||||
| 		DatabaseFactory factory{dbpath}; | 						 { migrationLogger << "Progress: Successfully migrated to: " << migration << Qt::endl; }); | ||||||
| 		auto db = factory.forCurrentThread(); | 		migrator.performMigrations(); | ||||||
| 		DBMigrator migrator{db}; | 		migrationLogger << "Database upgraded successfully" << Qt::endl; | ||||||
| 		if(migrator.migrationNeeded()) | 	} | ||||||
| 		{ | 	QVariant pdfViewer = settings.value(SETTINGS_KEY_PDFVIEWER); | ||||||
| 			QFile out; | 	if(!pdfViewer.isValid()) | ||||||
| 			out.open(stderr, QIODevice::WriteOnly); | 	{ | ||||||
| 			Logger migrationLogger{&out}; | 		setPdfViewer(); | ||||||
| 			migrationLogger << "Database is being upgraded, please be patient..." << Qt::endl; |  | ||||||
| 			QObject::connect(&migrator, &DBMigrator::migrationDone, |  | ||||||
| 							 [&migrationLogger](uint32_t migration) |  | ||||||
| 							 { migrationLogger << "Progress: Successfully migrated to: " << migration << Qt::endl; }); |  | ||||||
| 			migrator.performMigrations(); |  | ||||||
| 			migrationLogger << "Database upgraded successfully" << Qt::endl; |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -176,19 +165,18 @@ QString Common::ipcSocketPath() | |||||||
| 	// return settings.value(SETTINGS_KEY_IPCSOCKETPATH, "/tmp/.looqs/looqs-ipc-socket").toString(); | 	// return settings.value(SETTINGS_KEY_IPCSOCKETPATH, "/tmp/.looqs/looqs-ipc-socket").toString(); | ||||||
| } | } | ||||||
|  |  | ||||||
| static QStringList excludedPaths = {"/proc", "/sys", "/dev", "/tmp", "/var/run", "/run"}; |  | ||||||
|  |  | ||||||
| QStringList Common::excludedPaths() | QStringList Common::excludedPaths() | ||||||
| { | { | ||||||
| 	static int ran = false; | 	static int ran = false; | ||||||
|  | 	static QStringList excludedPaths; | ||||||
| 	if(!ran) | 	if(!ran) | ||||||
| 	{ | 	{ | ||||||
| 		QSettings settings; | 		QSettings settings; | ||||||
| 		QStringList userExcludedPaths = settings.value(SETTINGS_KEY_EXCLUDEDPATHS).toStringList(); | 		QStringList defaults{"/proc", "/sys", "/dev", "/tmp", "/var/run", "/run"}; | ||||||
|  | 		excludedPaths = settings.value(SETTINGS_KEY_EXCLUDEDPATHS, defaults).toStringList(); | ||||||
| 		ran = true; | 		ran = true; | ||||||
| 		::excludedPaths.append(userExcludedPaths); |  | ||||||
| 	} | 	} | ||||||
| 	return ::excludedPaths; | 	return excludedPaths; | ||||||
| } | } | ||||||
|  |  | ||||||
| QStringList Common::mountPaths() | QStringList Common::mountPaths() | ||||||
|   | |||||||
| @@ -2,6 +2,14 @@ | |||||||
| #define COMMON_H | #define COMMON_H | ||||||
| #include <QCoreApplication> | #include <QCoreApplication> | ||||||
| #include <QFileInfo> | #include <QFileInfo> | ||||||
|  |  | ||||||
|  | #define SETTINGS_KEY_DBPATH "dbpath" | ||||||
|  | #define SETTINGS_KEY_IPCSOCKETPATH "ipcsocketpath" | ||||||
|  | #define SETTINGS_KEY_PDFVIEWER "pdfviewer" | ||||||
|  | #define SETTINGS_KEY_EXCLUDEDPATHS "excludedpaths" | ||||||
|  | #define SETTINGS_KEY_MOUNTPATHS "mountpaths" | ||||||
|  | #define SETTINGS_KEY_PREVIEWSPERPAGE "previewsPerPage" | ||||||
|  |  | ||||||
| namespace Common | namespace Common | ||||||
| { | { | ||||||
| void setupAppInfo(); | void setupAppInfo(); | ||||||
|   | |||||||
| @@ -19,7 +19,21 @@ void Indexer::beginIndexing() | |||||||
| 	QVector<QString> dirs; | 	QVector<QString> dirs; | ||||||
|  |  | ||||||
| 	WildcardMatcher wildcardMatcher; | 	WildcardMatcher wildcardMatcher; | ||||||
| 	wildcardMatcher.setPatterns(this->ignorePattern); |  | ||||||
|  | 	QStringList ignoreList = this->ignorePattern; | ||||||
|  |  | ||||||
|  | 	for(QString &excludedPath : Common::excludedPaths()) | ||||||
|  | 	{ | ||||||
|  | 		QString pattern = excludedPath; | ||||||
|  | 		if(!pattern.endsWith("/")) | ||||||
|  | 		{ | ||||||
|  | 			pattern += "/"; | ||||||
|  | 		} | ||||||
|  | 		pattern += "*"; | ||||||
|  | 		ignoreList.append(excludedPath); | ||||||
|  | 	} | ||||||
|  | 	ignoreList.append(this->ignorePattern); | ||||||
|  | 	wildcardMatcher.setPatterns(ignoreList); | ||||||
| 	for(QString &path : this->pathsToScan) | 	for(QString &path : this->pathsToScan) | ||||||
| 	{ | 	{ | ||||||
| 		if(wildcardMatcher.match(path)) | 		if(wildcardMatcher.match(path)) | ||||||
| @@ -40,7 +54,7 @@ void Indexer::beginIndexing() | |||||||
| 	if(!dirs.empty()) | 	if(!dirs.empty()) | ||||||
| 	{ | 	{ | ||||||
| 		this->dirScanner->setPaths(dirs); | 		this->dirScanner->setPaths(dirs); | ||||||
| 		this->dirScanner->setIgnorePatterns(this->ignorePattern); | 		this->dirScanner->setIgnorePatterns(ignoreList); | ||||||
|  |  | ||||||
| 		this->dirScanner->scan(); | 		this->dirScanner->scan(); | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -23,12 +23,12 @@ QueryType LooqsQuery::getQueryType() | |||||||
| 	return static_cast<QueryType>(tokensMask & COMBINED); | 	return static_cast<QueryType>(tokensMask & COMBINED); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool LooqsQuery::hasContentSearch() | bool LooqsQuery::hasContentSearch() const | ||||||
| { | { | ||||||
| 	return (this->getTokensMask() & FILTER_CONTENT) == FILTER_CONTENT; | 	return (this->getTokensMask() & FILTER_CONTENT) == FILTER_CONTENT; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool LooqsQuery::hasPathSearch() | bool LooqsQuery::hasPathSearch() const | ||||||
| { | { | ||||||
| 	return (this->getTokensMask() & FILTER_PATH) == FILTER_PATH; | 	return (this->getTokensMask() & FILTER_PATH) == FILTER_PATH; | ||||||
| } | } | ||||||
| @@ -181,8 +181,8 @@ LooqsQuery LooqsQuery::build(QString expression, TokenType loneWordsTokenType, b | |||||||
| 	QStringList loneWords; | 	QStringList loneWords; | ||||||
| 	LooqsQuery result; | 	LooqsQuery result; | ||||||
| 	QRegularExpression rx( | 	QRegularExpression rx( | ||||||
| 		"((?<filtername>(\\.|\\w)+):(?<args>\\((?<innerargs>[^\\)]+)\\)|([\\p{L},])+)|(?<boolean>AND|OR)" | 		"((?<filtername>(\\.|\\w)+):(?<args>\\((?<innerargs>[^\\)]+)\\)|([\\p{L}\\p{N},])+)|(?<boolean>AND|OR)" | ||||||
| 		"|(?<negation>!)|(?<bracket>\\(|\\))|(?<loneword>[\"\\p{L}]+))"); | 		"|(?<negation>!)|(?<bracket>\\(|\\))|(?<loneword>[\"\\p{L}\\p{N}]+))"); | ||||||
| 	QRegularExpressionMatchIterator i = rx.globalMatch(expression); | 	QRegularExpressionMatchIterator i = rx.globalMatch(expression); | ||||||
| 	auto previousWasBool = [&result] { return !result.tokens.empty() && ((result.tokens.last().type & BOOL) == BOOL); }; | 	auto previousWasBool = [&result] { return !result.tokens.empty() && ((result.tokens.last().type & BOOL) == BOOL); }; | ||||||
| 	auto previousWas = [&result](TokenType t) { return !result.tokens.empty() && (result.tokens.last().type == t); }; | 	auto previousWas = [&result](TokenType t) { return !result.tokens.empty() && (result.tokens.last().type == t); }; | ||||||
|   | |||||||
| @@ -61,8 +61,8 @@ class LooqsQuery | |||||||
| 	{ | 	{ | ||||||
| 		this->limit = limit; | 		this->limit = limit; | ||||||
| 	} | 	} | ||||||
| 	bool hasContentSearch(); | 	bool hasContentSearch() const; | ||||||
| 	bool hasPathSearch(); | 	bool hasPathSearch() const; | ||||||
|  |  | ||||||
| 	void addSortCondition(SortCondition sc); | 	void addSortCondition(SortCondition sc); | ||||||
| 	static bool checkParanthesis(QString query); | 	static bool checkParanthesis(QString query); | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ void SandboxedProcessor::enableSandbox(QString readablePath) | |||||||
| 	struct exile_policy *policy = exile_init_policy(); | 	struct exile_policy *policy = exile_init_policy(); | ||||||
| 	if(policy == NULL) | 	if(policy == NULL) | ||||||
| 	{ | 	{ | ||||||
| 		qCritical() << "Could not init exile"; | 		qCritical() << "Could not init exile" << Qt::endl; | ||||||
| 		exit(EXIT_FAILURE); | 		exit(EXIT_FAILURE); | ||||||
| 	} | 	} | ||||||
| 	policy->namespace_options = EXILE_UNSHARE_NETWORK | EXILE_UNSHARE_USER; | 	policy->namespace_options = EXILE_UNSHARE_NETWORK | EXILE_UNSHARE_USER; | ||||||
| @@ -43,6 +43,8 @@ void SandboxedProcessor::enableSandbox(QString readablePath) | |||||||
| 	std::string readablePathLocation; | 	std::string readablePathLocation; | ||||||
| 	if(!readablePath.isEmpty()) | 	if(!readablePath.isEmpty()) | ||||||
| 	{ | 	{ | ||||||
|  | 		policy->namespace_options |= EXILE_UNSHARE_MOUNT; | ||||||
|  | 		policy->mount_path_policies_to_chroot = 1; | ||||||
| 		readablePathLocation = readablePath.toStdString(); | 		readablePathLocation = readablePath.toStdString(); | ||||||
| 		if(exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ, readablePathLocation.c_str()) != 0) | 		if(exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ, readablePathLocation.c_str()) != 0) | ||||||
| 		{ | 		{ | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ class SearchResult | |||||||
|   public: |   public: | ||||||
| 	FileData fileData; | 	FileData fileData; | ||||||
| 	QVector<unsigned int> pages; | 	QVector<unsigned int> pages; | ||||||
|  | 	bool wasContentSearch = false; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif // SEARCHRESULT_H | #endif // SEARCHRESULT_H | ||||||
|   | |||||||
| @@ -213,6 +213,7 @@ QVector<SearchResult> SqliteSearch::search(const LooqsQuery &query) | |||||||
| 		throw LooqsGeneralException("SQL Error: " + dbQuery.lastError().text()); | 		throw LooqsGeneralException("SQL Error: " + dbQuery.lastError().text()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	bool contentSearch = query.hasContentSearch(); | ||||||
| 	while(dbQuery.next()) | 	while(dbQuery.next()) | ||||||
| 	{ | 	{ | ||||||
| 		SearchResult result; | 		SearchResult result; | ||||||
| @@ -229,6 +230,7 @@ QVector<SearchResult> SqliteSearch::search(const LooqsQuery &query) | |||||||
| 				result.pages.append(page.toUInt()); | 				result.pages.append(page.toUInt()); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		result.wasContentSearch = contentSearch; | ||||||
| 		results.append(result); | 		results.append(result); | ||||||
| 	} | 	} | ||||||
| 	return results; | 	return results; | ||||||
|   | |||||||
 Submodule submodules/exile.h updated: 42d44b0cc1...8f38dc4480
									
								
							
		Fai riferimento in un nuovo problema
	
	Block a user