Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea
__pycache__
22 changes: 22 additions & 0 deletions UI/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,28 @@ def __init__(self):
super().__init__()
self.setupUi(self)

# Connect buttons to functions
self.convert.clicked.connect(self.onConvertClicked)
self.copyButton.clicked.connect(self.onCopyClicked)

def onConvertClicked(self):
# For now, just show a message - conversion logic will be added later
self.msg.setText("Conversion functionality will be implemented soon!")

def onCopyClicked(self):
# Copy the content of the output text area to clipboard
clipboard = QApplication.clipboard()
clipboard.setText(self.harvardTextBox.toPlainText())

# Show a temporary message
original_msg = self.msg.text()
self.msg.setText("✓ Copied to clipboard!")

# Reset message after 2 seconds
from PySide6.QtCore import QTimer

QTimer.singleShot(2000, lambda: self.msg.setText(original_msg))


if __name__ == "__main__":
app = QApplication(sys.argv)
Expand Down
200 changes: 161 additions & 39 deletions UI/myui.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

import sys

from PySide6.QtCore import (
QCoreApplication,
QDate,
Expand Down Expand Up @@ -43,6 +45,7 @@
from PySide6.QtWidgets import (
QApplication,
QGridLayout,
QHBoxLayout,
QLabel,
QMainWindow,
QMenuBar,
Expand All @@ -51,6 +54,7 @@
QSpacerItem,
QStatusBar,
QTextEdit,
QVBoxLayout,
QWidget,
)

Expand All @@ -59,84 +63,202 @@ class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
MainWindow.resize(900, 600)
MainWindow.setMinimumSize(QSize(800, 500))

# Center the window on screen
screen = QApplication.primaryScreen()
screen_geometry = screen.geometry()
window_geometry = MainWindow.geometry()
MainWindow.move(
(screen_geometry.width() - window_geometry.width()) // 2,
(screen_geometry.height() - window_geometry.height()) // 2,
)

self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayoutWidget = QWidget(self.centralwidget)
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayoutWidget.setGeometry(QRect(100, 40, 591, 481))
self.gridLayout = QGridLayout(self.gridLayoutWidget)
self.gridLayout.setObjectName("gridLayout")
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.msg = QLabel(self.gridLayoutWidget)
self.msg.setObjectName("msg")
self.msg.setMinimumSize(QSize(0, 80))

self.gridLayout.addWidget(self.msg, 3, 0, 1, 3)
# Main vertical layout
self.mainLayout = QVBoxLayout(self.centralwidget)
self.mainLayout.setObjectName("mainLayout")
self.mainLayout.setContentsMargins(20, 20, 20, 20)
self.mainLayout.setSpacing(15)

self.harvardTextBox = QTextEdit(self.gridLayoutWidget)
self.harvardTextBox.setObjectName("harvardTextBox")
# Horizontal layout for the two text areas
self.textAreasLayout = QHBoxLayout()
self.textAreasLayout.setObjectName("textAreasLayout")
self.textAreasLayout.setSpacing(15)

# Left side: BibTeX input area with layout
self.inputGroup = QWidget()
self.inputGroup.setObjectName("inputGroup")
self.inputLayout = QVBoxLayout(self.inputGroup)
self.inputLayout.setObjectName("inputLayout")
self.inputLayout.setContentsMargins(0, 0, 0, 0)
self.inputLayout.setSpacing(5)

self.gridLayout.addWidget(self.harvardTextBox, 1, 2, 1, 1)
self.label_2 = QLabel(self.inputGroup)
self.label_2.setObjectName("label_2")
self.label_2.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.inputLayout.addWidget(self.label_2)

self.bibTexBox = QTextEdit(self.gridLayoutWidget)
self.bibTexBox = QTextEdit(self.inputGroup)
self.bibTexBox.setObjectName("bibTexBox")
self.inputLayout.addWidget(self.bibTexBox)

self.gridLayout.addWidget(self.bibTexBox, 1, 0, 1, 1)
self.textAreasLayout.addWidget(self.inputGroup)

self.convert = QPushButton(self.gridLayoutWidget)
self.convert.setObjectName("convert")
# Right side: Harvard output area with layout and copy button
self.outputGroup = QWidget()
self.outputGroup.setObjectName("outputGroup")
self.outputLayout = QVBoxLayout(self.outputGroup)
self.outputLayout.setObjectName("outputLayout")
self.outputLayout.setContentsMargins(0, 0, 0, 0)
self.outputLayout.setSpacing(5)

self.gridLayout.addWidget(self.convert, 1, 1, 1, 1)
self.label_3 = QLabel(self.outputGroup)
self.label_3.setObjectName("label_3")
self.label_3.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.outputLayout.addWidget(self.label_3)

self.horizontalSpacer = QSpacerItem(
40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum
)
# Output text area with copy button container
self.outputTextContainer = QWidget()
self.outputTextContainer.setObjectName("outputTextContainer")
self.outputTextLayout = QVBoxLayout(self.outputTextContainer)
self.outputTextLayout.setObjectName("outputTextLayout")
self.outputTextLayout.setContentsMargins(0, 0, 0, 0)
self.outputTextLayout.setSpacing(5)

self.harvardTextBox = QTextEdit(self.outputTextContainer)
self.harvardTextBox.setObjectName("harvardTextBox")
self.harvardTextBox.setReadOnly(True) # Make output read-only
self.outputTextLayout.addWidget(self.harvardTextBox)

self.gridLayout.addItem(self.horizontalSpacer, 2, 1, 1, 1)
# Copy button at bottom-right
self.copyButtonLayout = QHBoxLayout()
self.copyButtonLayout.setObjectName("copyButtonLayout")
self.copyButtonLayout.addStretch() # Push button to right

self.label_2 = QLabel(self.gridLayoutWidget)
self.label_2.setObjectName("label_2")
self.label_2.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.copyButton = QPushButton(self.outputTextContainer)
self.copyButton.setObjectName("copyButton")
self.copyButtonLayout.addWidget(self.copyButton)

self.gridLayout.addWidget(self.label_2, 0, 0, 1, 1)
self.outputTextLayout.addLayout(self.copyButtonLayout)
self.outputLayout.addWidget(self.outputTextContainer)

self.label_3 = QLabel(self.gridLayoutWidget)
self.label_3.setObjectName("label_3")
self.label_3.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.textAreasLayout.addWidget(self.outputGroup)
self.mainLayout.addLayout(self.textAreasLayout)

# Convert button centered at the bottom
self.buttonLayout = QHBoxLayout()
self.buttonLayout.setObjectName("buttonLayout")
self.buttonLayout.addStretch()

self.gridLayout.addWidget(self.label_3, 0, 2, 1, 1)
self.convert = QPushButton(self.centralwidget)
self.convert.setObjectName("convert")
self.buttonLayout.addWidget(self.convert)

self.label_4 = QLabel(self.gridLayoutWidget)
self.label_4.setObjectName("label_4")
self.buttonLayout.addStretch()
self.mainLayout.addLayout(self.buttonLayout)

self.gridLayout.addWidget(self.label_4, 2, 0, 1, 1)
# Message label
self.msg = QLabel(self.centralwidget)
self.msg.setObjectName("msg")
self.msg.setMinimumSize(QSize(0, 30))
self.msg.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.mainLayout.addWidget(self.msg)

MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QMenuBar(MainWindow)
self.menubar.setObjectName("menubar")
self.menubar.setGeometry(QRect(0, 0, 800, 22))
self.menubar.setGeometry(QRect(0, 0, 900, 22))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)

# Apply UNSW branding colors
self.applyUNSWBranding(MainWindow)

self.retranslateUi(MainWindow)

QMetaObject.connectSlotsByName(MainWindow)

# setupUi

def applyUNSWBranding(self, MainWindow):
# UNSW official brand colors (updated)
unsw_yellow = QColor("#FFE600") # Primary: UNSW Yellow
unsw_charcoal = QColor("#231F20") # Secondary: Charcoal
unsw_light_grey = QColor("#F5F5F5") # Light background for read-only

# Set window title bar color (Windows only)
try:
MainWindow.setStyleSheet(
f"""
QMainWindow {{
background-color: #FFFFFF;
}}
QLabel {{
font-weight: 500;
color: {unsw_charcoal.name()};
}}
QPushButton {{
background-color: {unsw_yellow.name()};
color: {unsw_charcoal.name()};
border: 2px solid {unsw_charcoal.name()};
padding: 8px 24px;
font-weight: 600;
border-radius: 4px;
}}
QPushButton:hover {{
background-color: {unsw_charcoal.name()};
color: {unsw_yellow.name()};
}}
QPushButton:pressed {{
background-color: #{int(unsw_charcoal.rgb() & 0xFFFFFF) - 0x222222:06x};
}}
QTextEdit {{
border: 2px solid {unsw_charcoal.name()};
border-radius: 4px;
padding: 8px;
font-family: 'Courier New', monospace;
font-size: 10pt;
}}
QTextEdit:focus {{
border-color: {unsw_yellow.name()};
outline: none;
}}
"""
)
except (TypeError, ValueError, AttributeError) as e:
# Log style sheet errors but continue execution
print(f"Warning: Could not apply complete styling: {e}", file=sys.stderr)

# Set placeholder text for input text area
self.bibTexBox.setPlaceholderText("Paste BibTeX Here")

# Set read-only appearance for output text area
palette = self.harvardTextBox.palette()
palette.setColor(QPalette.ColorRole.Base, unsw_light_grey)
self.harvardTextBox.setPalette(palette)

def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(
QCoreApplication.translate("MainWindow", "MainWindow", None)
QCoreApplication.translate(
"MainWindow", "UNSW Harvard Reference Generator", None
)
)
self.msg.setText("")
self.convert.setText(QCoreApplication.translate("MainWindow", "Convert", None))
self.label_2.setText(QCoreApplication.translate("MainWindow", "BibTeX", None))
self.copyButton.setText(QCoreApplication.translate("MainWindow", "Copy", None))
self.label_2.setText(
QCoreApplication.translate("MainWindow", "BibTeX Input", None)
)
self.label_3.setText(
QCoreApplication.translate("MainWindow", "Harvard(UNSW)", None)
QCoreApplication.translate(
"MainWindow", "Harvard Reference (UNSW Style)", None
)
)
self.label_4.setText(QCoreApplication.translate("MainWindow", "Message:", None))

# retranslateUi
81 changes: 81 additions & 0 deletions USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# UNSW Harvard Reference Generator

A desktop application built with PySide6 for converting BibTeX entries from Google Scholar to UNSW Harvard reference style.

## Features

- **Clean UI**: Modern interface following UNSW branding guidelines
- **BibTeX Input**: Paste BibTeX entries from Google Scholar
- **Harvard Output**: View formatted UNSW Harvard references
- **Copy Functionality**: Quick copy to clipboard
- **Responsive Design**: Centered window with minimum size constraints

## Installation

1. **Clone the repository**:
```bash
git clone <repository-url>
cd UNSWHarvardReferenceFormatGeneration
```

2. **Activate the virtual environment**:
```bash
# Windows
.venv\Scripts\activate

# macOS/Linux
source .venv/bin/activate
```

3. **Install dependencies**:
```bash
pip install -r UI/requirements.txt
```

## Usage

1. **Run the application**:
```bash
# Windows
.venv\Scripts\python UI\main.py

# macOS/Linux
.venv/bin/python UI/main.py
```

2. **Paste BibTeX content** into the left text area

3. **Click "Convert"** (conversion logic coming soon)

4. **Copy the generated Harvard reference** using the Copy button

## UI Layout

- **Left Panel**: BibTeX input area with placeholder text
- **Right Panel**: Read-only Harvard reference output with Copy button
- **Bottom Center**: Prominent Convert button
- **Status Bar**: Feedback messages

## Branding

Uses official UNSW colors:
- Primary: UNSW Blue (#00338D)
- Secondary: UNSW Gold (#FFB81C)
- Light Blue: #E6EDF6 (for read-only areas)

## Technical Stack

- **Python 3.12+**
- **PySide6** - Qt UI framework
- **Qt Designer** - UI layout design

## Development

To modify the UI:
1. Edit `UI/main.ui` using Qt Designer
2. Regenerate Python code: `pyside6-uic UI/main.ui -o UI/myui.py`
3. Update functionality in `UI/main.py`

## License

MIT