Actualizaciones varias: mejoras en cuenta, sincronización, UI
This commit is contained in:
+145
-18
@@ -60,22 +60,22 @@ void RichTextEditor::setupToolbar(QVBoxLayout *layout) {
|
||||
m_toolbar->addSeparator();
|
||||
|
||||
// Alignment
|
||||
QAction *alignLeft = m_toolbar->addAction("\\xe2\\x87\\x94L");
|
||||
QAction *alignLeft = m_toolbar->addAction("L");
|
||||
connect(alignLeft, &QAction::triggered, this, &RichTextEditor::onAlignLeft);
|
||||
|
||||
QAction *alignCenter = m_toolbar->addAction("\\xe2\\x86\\x94C");
|
||||
QAction *alignCenter = m_toolbar->addAction("C");
|
||||
connect(alignCenter, &QAction::triggered, this, &RichTextEditor::onAlignCenter);
|
||||
|
||||
QAction *alignRight = m_toolbar->addAction("\\xe2\\x87\\x94R");
|
||||
QAction *alignRight = m_toolbar->addAction("R");
|
||||
connect(alignRight, &QAction::triggered, this, &RichTextEditor::onAlignRight);
|
||||
|
||||
QAction *alignJustify = m_toolbar->addAction("\\xe2\\x87\\x94J");
|
||||
QAction *alignJustify = m_toolbar->addAction("J");
|
||||
connect(alignJustify, &QAction::triggered, this, &RichTextEditor::onAlignJustify);
|
||||
|
||||
m_toolbar->addSeparator();
|
||||
|
||||
// Lists
|
||||
QAction *bulletAct = m_toolbar->addAction("\\xe2\\x80\\xa2 List");
|
||||
QAction *bulletAct = m_toolbar->addAction("Bullets");
|
||||
connect(bulletAct, &QAction::triggered, this, &RichTextEditor::onBulletList);
|
||||
|
||||
QAction *numAct = m_toolbar->addAction("1. List");
|
||||
@@ -84,23 +84,40 @@ void RichTextEditor::setupToolbar(QVBoxLayout *layout) {
|
||||
m_toolbar->addSeparator();
|
||||
|
||||
// Indent / Outdent
|
||||
QAction *indentAct = m_toolbar->addAction("\\xe2\\x86\\x92 Indent");
|
||||
QAction *indentAct = m_toolbar->addAction("Indent");
|
||||
connect(indentAct, &QAction::triggered, this, &RichTextEditor::onIndent);
|
||||
|
||||
QAction *outdentAct = m_toolbar->addAction("\\xe2\\x86\\x90 Outdent");
|
||||
QAction *outdentAct = m_toolbar->addAction("Outdent");
|
||||
connect(outdentAct, &QAction::triggered, this, &RichTextEditor::onOutdent);
|
||||
|
||||
m_toolbar->addSeparator();
|
||||
|
||||
// Insert image
|
||||
QAction *imgAct = m_toolbar->addAction("\\xf0\\x9f\\x96\\xbc Image");
|
||||
connect(imgAct, &QAction::triggered, this, &RichTextEditor::onInsertImage);
|
||||
QAction *imgAct = m_toolbar->addAction("Img");
|
||||
connect(imgAct, &QAction::triggered, this, &RichTextEditor::onInsertImage);
|
||||
|
||||
// Insert table
|
||||
QAction *tableAct = m_toolbar->addAction("\\xe2\\x96\\xa4 Table");
|
||||
connect(tableAct, &QAction::triggered, this, &RichTextEditor::onInsertTable);
|
||||
// Insert table
|
||||
QAction *tableAct = m_toolbar->addAction("Tbl");
|
||||
connect(tableAct, &QAction::triggered, this, &RichTextEditor::onInsertTable);
|
||||
|
||||
layout->addWidget(m_toolbar);
|
||||
// Signature button
|
||||
m_signatureButton = new QToolButton();
|
||||
m_signatureButton->setText("Signature");
|
||||
m_signatureButton->setToolButtonStyle(Qt::ToolButtonTextOnly);
|
||||
m_signatureButton->setPopupMode(QToolButton::MenuButtonPopup);
|
||||
m_signatureMenu = new QMenu(m_signatureButton);
|
||||
m_signatureButton->setMenu(m_signatureMenu);
|
||||
m_signatureButton->setStyleSheet(
|
||||
"QToolButton { background: #f5f5f7; border: 1px solid #d1d1d6; border-radius: 3px; padding: 4px 6px; }"
|
||||
"QToolButton:hover { background: #e0e0e0; }"
|
||||
"QToolButton::menu-button { border-left: 1px solid rgba(0,0,0,0.1); width: 12px; }"
|
||||
);
|
||||
connect(m_signatureButton, &QToolButton::clicked, this, &RichTextEditor::signatureClicked);
|
||||
m_toolbar->addWidget(m_signatureButton);
|
||||
|
||||
m_toolbar->addSeparator();
|
||||
|
||||
layout->addWidget(m_toolbar);
|
||||
}
|
||||
|
||||
void RichTextEditor::onBold() {
|
||||
@@ -244,12 +261,99 @@ void RichTextEditor::onInsertTable() {
|
||||
cursor.insertTable(rows, cols, tableFmt);
|
||||
}
|
||||
|
||||
// ===================== ComposeView =====================
|
||||
|
||||
ComposeView::ComposeView(QWidget *parent) : QWidget(parent) {
|
||||
setupUI();
|
||||
// Connect the rich text editor's signature signal to our slot
|
||||
connect(m_bodyEditor, &RichTextEditor::signatureClicked, this, &ComposeView::onSignatureClicked);
|
||||
}
|
||||
|
||||
ComposeView::~ComposeView() {
|
||||
// Destructor implementation
|
||||
}
|
||||
void ComposeView::onSignatureClicked() {
|
||||
// This slot is called when the signature button in the rich text editor is clicked
|
||||
// The actual menu handling is done in RichTextEditor, so we just need to
|
||||
// handle any ComposeView-specific logic here if needed
|
||||
}
|
||||
|
||||
void ComposeView::onSignatureEditRequested() {
|
||||
// This slot will be connected to the "Edit Signature..." action in the menu
|
||||
// For now, we'll just show a simple input dialog
|
||||
QString currentSignature = "";
|
||||
// In a real implementation, we would get the current signature for the selected account
|
||||
// For now, we'll use an empty string
|
||||
|
||||
bool ok;
|
||||
QString newSignature = QInputDialog::getMultiLineText(this, "Edit Signature",
|
||||
"Enter your signature:",
|
||||
currentSignature, &ok);
|
||||
if (ok && !newSignature.isEmpty()) {
|
||||
// In a real implementation, we would save this signature for the selected account
|
||||
// For now, we'll just insert it at the cursor position
|
||||
QTextCursor cursor = m_bodyEditor->textCursor();
|
||||
cursor.insertHtml(newSignature);
|
||||
}
|
||||
}
|
||||
|
||||
void ComposeView::setAccountService(AccountService *service)
|
||||
{
|
||||
m_accountService = service;
|
||||
populateAccountCombo();
|
||||
}
|
||||
|
||||
void ComposeView::populateAccountCombo()
|
||||
{
|
||||
if (!m_accountService) {
|
||||
qWarning() << "AccountService not set";
|
||||
return;
|
||||
}
|
||||
|
||||
m_accountCombo->clear();
|
||||
m_accountCombo->addItem(tr("Select Account..."), QVariant());
|
||||
|
||||
QVector<Account> accounts = m_accountService->getAllAccounts();
|
||||
for (const Account &account : accounts) {
|
||||
m_accountCombo->addItem(account.email(), account.id());
|
||||
}
|
||||
|
||||
// Select the first account by default if there are accounts
|
||||
if (accounts.size() > 0) {
|
||||
m_accountCombo->setCurrentIndex(1); // Skip the placeholder item
|
||||
m_currentAccountId = accounts.first().id();
|
||||
}
|
||||
}
|
||||
|
||||
void ComposeView::onAccountChanged(int index)
|
||||
{
|
||||
if (index <= 0) {
|
||||
// Placeholder item selected or invalid index
|
||||
m_currentAccountId = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentAccountId = m_accountCombo->itemData(index).toInt();
|
||||
loadSignatureForCurrentAccount();
|
||||
}
|
||||
|
||||
void ComposeView::loadSignatureForCurrentAccount()
|
||||
{
|
||||
if (!m_accountService || m_currentAccountId <= 0) {
|
||||
// Clear signature if no account selected
|
||||
m_bodyEditor->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
Account* account = m_accountService->findAccountById(m_currentAccountId);
|
||||
if (account) {
|
||||
// For now, we'll just clear the editor since we don't have a signature field in Account yet
|
||||
// In a real implementation, we would retrieve and display the signature
|
||||
m_bodyEditor->clear();
|
||||
} else {
|
||||
m_bodyEditor->clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ComposeView::setupUI() {
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setContentsMargins(20, 15, 20, 15);
|
||||
@@ -271,7 +375,7 @@ void ComposeView::setupUI() {
|
||||
m_subjectField->setFont(subjectFont);
|
||||
headerLayout->addWidget(m_subjectField, 1);
|
||||
|
||||
m_detachButton = new QPushButton("\\xe2\\x87\\xa5 Detach");
|
||||
m_detachButton = new QPushButton("\xe2\x87\xa5 Detach");
|
||||
m_detachButton->setToolTip("Open compose window in a separate window");
|
||||
m_detachButton->setStyleSheet(
|
||||
"QPushButton { background: transparent; border: 1px solid #d1d1d6; border-radius: 4px; padding: 6px 12px; color: #555; font-size: 12px; }"
|
||||
@@ -288,6 +392,27 @@ void ComposeView::setupUI() {
|
||||
line1->setStyleSheet("color: #e0e0e0;");
|
||||
mainLayout->addWidget(line1);
|
||||
|
||||
// From: field + Account selector
|
||||
QHBoxLayout *fromLayout = new QHBoxLayout();
|
||||
QLabel *fromLabel = new QLabel("From:");
|
||||
fromLabel->setFixedWidth(40);
|
||||
fromLabel->setStyleSheet("font-weight: bold; color: #555;");
|
||||
m_accountCombo = new QComboBox();
|
||||
m_accountCombo->setFixedWidth(180);
|
||||
m_accountCombo->setStyleSheet(
|
||||
"QComboBox { border: 1px solid #d1d1d6; border-radius: 4px; padding: 6px 8px; "
|
||||
"background: white; min-height: 20px; }"
|
||||
"QComboBox:hover { border-color: #bdbdbd; }"
|
||||
"QComboBox:focus { border-color: #1976D2; }"
|
||||
"QComboBox::drop-down { border: none; width: 20px; }"
|
||||
"QComboBox::down-arrow { image: url(:/icons/dropdown.png); width: 10px; height: 10px; }"
|
||||
);
|
||||
connect(m_accountCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &ComposeView::onAccountChanged);
|
||||
fromLayout->addWidget(fromLabel);
|
||||
fromLayout->addWidget(m_accountCombo, 1);
|
||||
mainLayout->addLayout(fromLayout);
|
||||
|
||||
// To: field + Cc/Bcc toggle buttons
|
||||
QHBoxLayout *toLayout = new QHBoxLayout();
|
||||
QLabel *toLabel = new QLabel("To:");
|
||||
@@ -462,7 +587,8 @@ void ComposeView::onSendClicked() {
|
||||
m_bccVisible ? m_bccField->text() : QString(),
|
||||
m_subjectField->text(),
|
||||
m_bodyEditor->toHtml(),
|
||||
QDateTime() // null = send now
|
||||
QDateTime(), // null = send now
|
||||
m_currentAccountId > 0 ? m_accountCombo->itemData(m_accountCombo->currentIndex()).toString() : QString()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -473,7 +599,8 @@ void ComposeView::onScheduleClicked() {
|
||||
m_bccVisible ? m_bccField->text() : QString(),
|
||||
m_subjectField->text(),
|
||||
m_bodyEditor->toHtml(),
|
||||
m_schedulePicker->dateTime()
|
||||
m_schedulePicker->dateTime(),
|
||||
m_currentAccountId > 0 ? m_accountCombo->itemData(m_accountCombo->currentIndex()).toString() : QString()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user