From 9d4f4911cdd18d52ceb17902715895c872c26427 Mon Sep 17 00:00:00 2001 From: Axel Rafn Date: Fri, 12 Jul 2024 18:36:26 +0200 Subject: [PATCH] chore: Update .gitignore to ignore the contents of the "data" directory and add __pycache__/ --- .gitignore | 6 +- app.py | 164 ++++++++++++++++++++++++++++++++++------------------- 2 files changed, 110 insertions(+), 60 deletions(-) diff --git a/.gitignore b/.gitignore index e31bddc..23af79d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,8 @@ +# Ignore the virtual environment directory venv/ # ignore the contents of the directory data -data/* \ No newline at end of file +data/* + +# Ignore the pycache directory +__pycache__/ \ No newline at end of file diff --git a/app.py b/app.py index 52927e0..d2001f8 100644 --- a/app.py +++ b/app.py @@ -4,20 +4,19 @@ import os from PyQt5.QtWidgets import ( QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QPushButton, QListWidget, QTextEdit, QComboBox, - QMessageBox, QSpacerItem, QSizePolicy, QLabel, QFileDialog, QDialog, QFormLayout + QMessageBox, QSpacerItem, QSizePolicy, QLabel, QFileDialog, QDialog, QFormLayout, QTableWidget, QTableWidgetItem ) from PyQt5.QtGui import QIcon, QPixmap -from PyQt5.QtCore import Qt, QUrl +from PyQt5.QtCore import Qt, QUrl, QDateTime from PyQt5.QtSvg import QSvgWidget from PyQt5.QtGui import QDesktopServices - class URLManager(QWidget): def __init__(self): super().__init__() self.setWindowTitle('tabRemember - URL Manager') - self.setGeometry(100, 100, 340, 500) + self.setGeometry(100, 100, 400, 600) # Set the application icon self.setWindowIcon(QIcon('assets/logo.png')) @@ -56,7 +55,7 @@ class URLManager(QWidget): self.layout.addWidget(self.description_input) # Add URL button - self.add_button = QPushButton("Add URL") + self.add_button = QPushButton("Save") self.add_button.clicked.connect(self.add_url) self.layout.addWidget(self.add_button) @@ -66,10 +65,10 @@ class URLManager(QWidget): # Group selection and search input self.group_search_layout = QHBoxLayout() self.group_combobox = QComboBox() - self.group_combobox.addItem("Default") self.group_search_layout.addWidget(self.group_combobox) self.search_input = QLineEdit() self.search_input.setPlaceholderText("Search ...") + self.search_input.textChanged.connect(self.filter_urls) self.group_search_layout.addWidget(self.search_input) self.layout.addLayout(self.group_search_layout) @@ -78,16 +77,23 @@ class URLManager(QWidget): self.search_input.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) # URL list - self.url_list = QListWidget() + self.url_list = QTableWidget(0, 3) + self.url_list.setHorizontalHeaderLabels(['URL', 'Date', 'Actions']) + self.url_list.setColumnWidth(0, 200) + self.url_list.setColumnWidth(1, 100) self.layout.addWidget(self.url_list) self.setLayout(self.layout) - self.urls = {} + self.urls = [] + self.groups = set() # Load settings self.load_settings() + # Load URLs + self.load_urls() + # Search engines self.search_engines = { "Bing": "https://www.bing.com/search?q=", @@ -117,45 +123,112 @@ class URLManager(QWidget): description = self.description_input.toPlainText() group = self.group_combobox.currentText() if url: - self.url_list.addItem(f"{group}: {url}") - if group not in self.urls: - self.urls[group] = [] - self.urls[group].append({'url': url, 'description': description}) + date_added = QDateTime.currentDateTime().toString(Qt.ISODate) + self.urls.append({'url': url, 'description': description, 'date': date_added, 'group': group}) + self.save_urls() + self.update_url_list() self.url_input.clear() self.description_input.clear() def update_url(self): selected_item = self.url_list.currentItem() if selected_item: - group, url = selected_item.text().split(": ", 1) + row = self.url_list.row(selected_item) new_url = self.url_input.text() new_description = self.description_input.toPlainText() - selected_item.setText(f"{group}: {new_url}") - for item in self.urls[group]: - if item['url'] == url: - item['url'] = new_url - item['description'] = new_description - break + self.urls[row]['url'] = new_url + self.urls[row]['description'] = new_description + self.save_urls() + self.update_url_list() self.url_input.clear() self.description_input.clear() def delete_url(self): selected_item = self.url_list.currentItem() if selected_item: - group, url = selected_item.text().split(": ", 1) - self.url_list.takeItem(self.url_list.row(selected_item)) - for item in self.urls[group]: - if item['url'] == url: - self.urls[group].remove(item) - break + row = self.url_list.row(selected_item) + del self.urls[row] + self.save_urls() + self.update_url_list() - def search_url(self): - search_term = self.search_input.text() - if search_term: - search_engine_url = self.search_engines.get(self.search_engine, "https://www.google.com/search?q=") - search_url = search_engine_url + search_term - QMessageBox.information(self, "Search", f"Searching for: {search_term}\nURL: {search_url}") - self.search_input.clear() + def filter_urls(self): + search_term = self.search_input.text().lower() + filtered_urls = [url for url in self.urls if search_term in url['url'].lower() or search_term in url['description'].lower()] + self.update_url_list(filtered_urls) + + def update_url_list(self, urls=None): + if urls is None: + urls = self.urls + + self.url_list.setRowCount(0) + for url in urls: + row_position = self.url_list.rowCount() + self.url_list.insertRow(row_position) + self.url_list.setItem(row_position, 0, QTableWidgetItem(url['url'])) + self.url_list.setItem(row_position, 1, QTableWidgetItem(url['date'])) + + # Action buttons + actions_layout = QHBoxLayout() + edit_button = QPushButton("Edit") + delete_button = QPushButton("Delete") + edit_button.clicked.connect(lambda ch, row=row_position: self.edit_url(row)) + delete_button.clicked.connect(lambda ch, row=row_position: self.remove_url(row)) + actions_layout.addWidget(edit_button) + actions_layout.addWidget(delete_button) + actions_widget = QWidget() + actions_widget.setLayout(actions_layout) + self.url_list.setCellWidget(row_position, 2, actions_widget) + + def edit_url(self, row): + url = self.urls[row] + self.url_input.setText(url['url']) + self.description_input.setPlainText(url['description']) + self.urls.pop(row) + + def remove_url(self, row): + del self.urls[row] + self.save_urls() + self.update_url_list() + + def load_settings(self): + settings_path = 'data/settings.json' + if os.path.exists(settings_path): + if os.path.getsize(settings_path) > 0: + with open(settings_path, 'r') as file: + settings = json.load(file) + self.data_directory = settings.get('data_directory', 'data/') + self.search_engine = settings.get('search_engine', 'Google') + else: + self.data_directory = 'data/' + self.search_engine = 'Google' + self.save_settings() + else: + self.data_directory = 'data/' + self.search_engine = 'Google' + self.save_settings() + + def save_settings(self): + settings_path = 'data/settings.json' + os.makedirs(os.path.dirname(settings_path), exist_ok=True) + with open(settings_path, 'w') as file: + settings = { + 'data_directory': self.data_directory, + 'search_engine': self.search_engine + } + json.dump(settings, file) + + def load_urls(self): + urls_path = os.path.join(self.data_directory, 'urls.json') + if os.path.exists(urls_path): + with open(urls_path, 'r') as file: + self.urls = json.load(file) + self.update_url_list() + + def save_urls(self): + urls_path = os.path.join(self.data_directory, 'urls.json') + os.makedirs(os.path.dirname(urls_path), exist_ok=True) + with open(urls_path, 'w') as file: + json.dump(self.urls, file) def show_info_dialog(self): dialog = QDialog(self) @@ -185,33 +258,6 @@ class URLManager(QWidget): dialog = SettingsDialog(self) dialog.exec_() - def load_settings(self): - settings_path = 'data/settings.json' - if os.path.exists(settings_path): - if os.path.getsize(settings_path) > 0: - with open(settings_path, 'r') as file: - settings = json.load(file) - self.data_directory = settings.get('data_directory', 'data/') - self.search_engine = settings.get('search_engine', 'Google') - else: - self.data_directory = 'data/' - self.search_engine = 'Google' - self.save_settings() - else: - self.data_directory = 'data/' - self.search_engine = 'Google' - self.save_settings() - - def save_settings(self): - settings_path = 'data/settings.json' - os.makedirs(os.path.dirname(settings_path), exist_ok=True) - with open(settings_path, 'w') as file: - settings = { - 'data_directory': self.data_directory, - 'search_engine': self.search_engine - } - json.dump(settings, file) - class SettingsDialog(QDialog): def __init__(self, parent=None):