Add .gitignore and requirements.txt files
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
venv/
|
||||
4
THANKS.md
Normal file
4
THANKS.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Thanks go to
|
||||
|
||||
- [Sunna]() for the initial idea and her efforts in helping me with getting this off the ground.
|
||||
- [Bootstrap Icons](https://icons.getbootstrap.com/) for their epic icons.
|
||||
146
app.py
Normal file
146
app.py
Normal file
@ -0,0 +1,146 @@
|
||||
import sys
|
||||
from PyQt5.QtWidgets import (
|
||||
QApplication, QWidget, QVBoxLayout, QHBoxLayout,
|
||||
QLineEdit, QPushButton, QListWidget, QTextEdit, QComboBox, QMessageBox, QSpacerItem, QSizePolicy
|
||||
)
|
||||
from PyQt5.QtGui import QIcon, QPixmap
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtSvg import QSvgWidget
|
||||
|
||||
|
||||
class URLManager(QWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.setWindowTitle('tabRemember - URL Manager')
|
||||
self.setGeometry(100, 100, 340, 500)
|
||||
|
||||
# Set the application icon
|
||||
self.setWindowIcon(QIcon('assets/logo.png'))
|
||||
|
||||
self.layout = QVBoxLayout()
|
||||
|
||||
# URL input and settings button layout
|
||||
self.url_layout = QHBoxLayout()
|
||||
self.url_input = QLineEdit()
|
||||
self.url_input.setPlaceholderText("URL")
|
||||
self.url_layout.addWidget(self.url_input)
|
||||
|
||||
# Settings button
|
||||
self.settings_button = QPushButton()
|
||||
self.settings_button.setFixedHeight(self.url_input.sizeHint().height())
|
||||
self.settings_button.setFixedWidth(self.url_input.sizeHint().height())
|
||||
self.url_layout.addWidget(self.settings_button)
|
||||
|
||||
# Info button
|
||||
self.info_button = QPushButton()
|
||||
self.info_button.setFixedHeight(self.url_input.sizeHint().height())
|
||||
self.info_button.setFixedWidth(self.url_input.sizeHint().height())
|
||||
self.url_layout.addWidget(self.info_button)
|
||||
|
||||
self.layout.addLayout(self.url_layout)
|
||||
|
||||
# Update icons based on the color mode
|
||||
self.update_icon_color()
|
||||
|
||||
# Description/Thoughts input
|
||||
self.description_input = QTextEdit()
|
||||
self.description_input.setPlaceholderText("Enter Description or Thoughts")
|
||||
self.description_input.setMaximumHeight(100) # Limit height to approximately 5 lines
|
||||
self.layout.addWidget(self.description_input)
|
||||
|
||||
# Add URL button
|
||||
self.add_button = QPushButton("Add URL")
|
||||
self.add_button.clicked.connect(self.add_url)
|
||||
self.layout.addWidget(self.add_button)
|
||||
|
||||
# Add space between the Add URL button and URL list
|
||||
self.layout.addSpacerItem(QSpacerItem(0, 10, QSizePolicy.Minimum, QSizePolicy.Fixed))
|
||||
|
||||
# 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.group_search_layout.addWidget(self.search_input)
|
||||
self.layout.addLayout(self.group_search_layout)
|
||||
|
||||
# Ensure the dropdown and search input are of equal width
|
||||
self.group_combobox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
|
||||
self.search_input.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
|
||||
|
||||
# URL list
|
||||
self.url_list = QListWidget()
|
||||
self.layout.addWidget(self.url_list)
|
||||
|
||||
self.setLayout(self.layout)
|
||||
|
||||
self.urls = {}
|
||||
|
||||
def update_icon_color(self):
|
||||
# Heuristic to check if the application is in dark mode
|
||||
palette = self.palette()
|
||||
if palette.color(palette.Window).value() < 128:
|
||||
settings_icon_path = 'assets/cogwheel_dark.svg'
|
||||
info_icon_path = 'assets/info_dark.svg'
|
||||
else:
|
||||
settings_icon_path = 'assets/cogwheel_light.svg'
|
||||
info_icon_path = 'assets/info_light.svg'
|
||||
|
||||
self.settings_button.setIcon(QIcon(settings_icon_path))
|
||||
self.info_button.setIcon(QIcon(info_icon_path))
|
||||
|
||||
def add_url(self):
|
||||
url = self.url_input.text()
|
||||
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})
|
||||
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)
|
||||
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.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
|
||||
|
||||
def search_url(self):
|
||||
search_term = self.search_input.text()
|
||||
if search_term:
|
||||
search_engine = "https://www.google.com/search?q="
|
||||
search_url = search_engine + search_term
|
||||
QMessageBox.information(self, "Search", f"Searching for: {search_term}\nURL: {search_url}")
|
||||
self.search_input.clear()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QApplication(sys.argv)
|
||||
app.setWindowIcon(QIcon('assets/logo.png')) # Set the application icon using PNG for compatibility
|
||||
window = URLManager()
|
||||
window.show()
|
||||
sys.exit(app.exec_())
|
||||
4
assets/cogwheel_dark.svg
Normal file
4
assets/cogwheel_dark.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="#cecece" class="bi bi-gear" viewBox="0 0 16 16">
|
||||
<path d="M8 4.754a3.246 3.246 0 1 0 0 6.492 3.246 3.246 0 0 0 0-6.492M5.754 8a2.246 2.246 0 1 1 4.492 0 2.246 2.246 0 0 1-4.492 0"/>
|
||||
<path d="M9.796 1.343c-.527-1.79-3.065-1.79-3.592 0l-.094.319a.873.873 0 0 1-1.255.52l-.292-.16c-1.64-.892-3.433.902-2.54 2.541l.159.292a.873.873 0 0 1-.52 1.255l-.319.094c-1.79.527-1.79 3.065 0 3.592l.319.094a.873.873 0 0 1 .52 1.255l-.16.292c-.892 1.64.901 3.434 2.541 2.54l.292-.159a.873.873 0 0 1 1.255.52l.094.319c.527 1.79 3.065 1.79 3.592 0l.094-.319a.873.873 0 0 1 1.255-.52l.292.16c1.64.893 3.434-.902 2.54-2.541l-.159-.292a.873.873 0 0 1 .52-1.255l.319-.094c1.79-.527 1.79-3.065 0-3.592l-.319-.094a.873.873 0 0 1-.52-1.255l.16-.292c.893-1.64-.902-3.433-2.541-2.54l-.292.159a.873.873 0 0 1-1.255-.52zm-2.633.283c.246-.835 1.428-.835 1.674 0l.094.319a1.873 1.873 0 0 0 2.693 1.115l.291-.16c.764-.415 1.6.42 1.184 1.185l-.159.292a1.873 1.873 0 0 0 1.116 2.692l.318.094c.835.246.835 1.428 0 1.674l-.319.094a1.873 1.873 0 0 0-1.115 2.693l.16.291c.415.764-.42 1.6-1.185 1.184l-.291-.159a1.873 1.873 0 0 0-2.693 1.116l-.094.318c-.246.835-1.428.835-1.674 0l-.094-.319a1.873 1.873 0 0 0-2.692-1.115l-.292.16c-.764.415-1.6-.42-1.184-1.185l.159-.291A1.873 1.873 0 0 0 1.945 8.93l-.319-.094c-.835-.246-.835-1.428 0-1.674l.319-.094A1.873 1.873 0 0 0 3.06 4.377l-.16-.292c-.415-.764.42-1.6 1.185-1.184l.292.159a1.873 1.873 0 0 0 2.692-1.115z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
4
assets/cogwheel_light.svg
Normal file
4
assets/cogwheel_light.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="#212121" class="bi bi-gear" viewBox="0 0 16 16">
|
||||
<path d="M8 4.754a3.246 3.246 0 1 0 0 6.492 3.246 3.246 0 0 0 0-6.492M5.754 8a2.246 2.246 0 1 1 4.492 0 2.246 2.246 0 0 1-4.492 0"/>
|
||||
<path d="M9.796 1.343c-.527-1.79-3.065-1.79-3.592 0l-.094.319a.873.873 0 0 1-1.255.52l-.292-.16c-1.64-.892-3.433.902-2.54 2.541l.159.292a.873.873 0 0 1-.52 1.255l-.319.094c-1.79.527-1.79 3.065 0 3.592l.319.094a.873.873 0 0 1 .52 1.255l-.16.292c-.892 1.64.901 3.434 2.541 2.54l.292-.159a.873.873 0 0 1 1.255.52l.094.319c.527 1.79 3.065 1.79 3.592 0l.094-.319a.873.873 0 0 1 1.255-.52l.292.16c1.64.893 3.434-.902 2.54-2.541l-.159-.292a.873.873 0 0 1 .52-1.255l.319-.094c1.79-.527 1.79-3.065 0-3.592l-.319-.094a.873.873 0 0 1-.52-1.255l.16-.292c.893-1.64-.902-3.433-2.541-2.54l-.292.159a.873.873 0 0 1-1.255-.52zm-2.633.283c.246-.835 1.428-.835 1.674 0l.094.319a1.873 1.873 0 0 0 2.693 1.115l.291-.16c.764-.415 1.6.42 1.184 1.185l-.159.292a1.873 1.873 0 0 0 1.116 2.692l.318.094c.835.246.835 1.428 0 1.674l-.319.094a1.873 1.873 0 0 0-1.115 2.693l.16.291c.415.764-.42 1.6-1.185 1.184l-.291-.159a1.873 1.873 0 0 0-2.693 1.116l-.094.318c-.246.835-1.428.835-1.674 0l-.094-.319a1.873 1.873 0 0 0-2.692-1.115l-.292.16c-.764.415-1.6-.42-1.184-1.185l.159-.291A1.873 1.873 0 0 0 1.945 8.93l-.319-.094c-.835-.246-.835-1.428 0-1.674l.319-.094A1.873 1.873 0 0 0 3.06 4.377l-.16-.292c-.415-.764.42-1.6 1.185-1.184l.292.159a1.873 1.873 0 0 0 2.692-1.115z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
4
assets/info-circle.svg
Normal file
4
assets/info-circle.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16">
|
||||
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
|
||||
<path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 460 B |
BIN
assets/logo.png
Normal file
BIN
assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
4
assets/logo.svg
Normal file
4
assets/logo.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" fill="currentColor" class="bi bi-card-heading" viewBox="0 0 16 16">
|
||||
<path d="M14.5 3a.5.5 0 0 1 .5.5v9a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5zm-13-1A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2z"/>
|
||||
<path d="M3 8.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5m0 2a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5m0-5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-9a.5.5 0 0 1-.5-.5z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 548 B |
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
PyQT5
|
||||
Reference in New Issue
Block a user