#include "Introduction.h" #include "CompositionButton.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include Introduction::Introduction(QWidget *parent) : QDialog(parent), m_title(0), m_edit(0), m_editApply(0), m_existingCompositionBox(0) { #ifdef Q_OS_MAC QMenuBar *globalMenu = new QMenuBar(this); globalMenu->addMenu(QLatin1String("About"))->addAction(QLatin1String("About Author"), this, SLOT(about())); #endif setWindowTitle(tr("Author - Introduction")); QHBoxLayout *layout = new QHBoxLayout; QGroupBox *newCompositionBox = new QGroupBox(tr("Create a New Composition")); QVBoxLayout *newCompositionBoxLayout = new QVBoxLayout; QLabel *instructions = new QLabel(tr("

Welcome to Author. To get started with your finely authored composition, please enter a title.

")); QFont font; font.setFamily("CMU Typewriter Text Variable Width"); instructions->setFont(font); instructions->setWordWrap(true); QLabel *image = new QLabel; image->setPixmap(QPixmap(QLatin1String(":/journal.png"))); newCompositionBoxLayout->addWidget(instructions); newCompositionBoxLayout->addStretch(); newCompositionBoxLayout->addWidget(image, 0, Qt::AlignCenter); newCompositionBoxLayout->addStretch(); font.setPointSize(16); font.setBold(true); m_title = new QLineEdit(defaultName()); m_title->setFont(font); m_title->setAlignment(Qt::AlignCenter); newCompositionBoxLayout->addWidget(m_title); QPushButton *okay = new QPushButton(tr("Wonderful, let's begin!")); font.setPointSize(18); okay->setFont(font); connect(okay, SIGNAL(clicked()), this, SLOT(accept())); newCompositionBoxLayout->addWidget(okay); newCompositionBox->setLayout(newCompositionBoxLayout); layout->addWidget(newCompositionBox); QSettings s; bool hasExisting = false; foreach (const QString &title, s.childGroups()) { const QString key = QString("%1/lastModified").arg(title); if (s.contains(key)) { hasExisting = true; break; } } if (hasExisting) { m_existingCompositionBox = new QGroupBox(tr("Resume an Existing Composition")); QVBoxLayout *existingCompositionBoxLayout = new QVBoxLayout; existingCompositionBoxLayout->setSpacing(0); QMap sorter; foreach (const QString &title, s.childGroups()) { const QString key = QString("%1/lastModified").arg(title); if (s.contains(key)) sorter.insertMulti(s.value(key).toDateTime(), title); } QMapIterator i(sorter); while (i.hasNext()) { i.next(); CompositionButton *button = new CompositionButton(i.value(), i.key()); m_compositionButtons.append(button); connect(button, SIGNAL(selected()), this, SLOT(loadExisting())); existingCompositionBoxLayout->insertWidget(0, button); } existingCompositionBoxLayout->addStretch(); QWidget *container = new QWidget; container->setLayout(existingCompositionBoxLayout); QScrollArea *scroller = new QScrollArea; scroller->setFrameStyle(QFrame::NoFrame); scroller->setWidget(container); QVBoxLayout *scrollerLayout = new QVBoxLayout; scrollerLayout->setContentsMargins(0, 0, 0, 0); scrollerLayout->addWidget(scroller); container->setAutoFillBackground(false); scroller->viewport()->setAutoFillBackground(false); scroller->setMinimumWidth(scroller->sizeHint().width() + scroller->verticalScrollBar()->sizeHint().width()); m_edit = new QPushButton(QIcon(QLatin1String(":/renameremove.png")), tr("Rename or Remove")); connect(m_edit, SIGNAL(clicked()), this, SLOT(edit())); m_editApply = new QDialogButtonBox(QDialogButtonBox::Apply | QDialogButtonBox::Discard); m_editApply->setCenterButtons(true); connect(m_editApply, SIGNAL(clicked(QAbstractButton*)), this, SLOT(applyDiscard(QAbstractButton*))); scrollerLayout->addWidget(m_edit); m_existingCompositionBox->setLayout(scrollerLayout); layout->addWidget(m_existingCompositionBox); } setLayout(layout); setMinimumHeight(sizeHint().height()); setFixedWidth(sizeHint().width()); } Introduction::~Introduction() { if (m_existingCompositionBox) { if (m_edit) m_edit->deleteLater(); if (m_editApply) m_editApply->deleteLater(); } } QString Introduction::title() const { if (m_title->text().trimmed().length() == 0) return defaultName(); return m_title->text().trimmed(); } QString Introduction::defaultName() const { int index = 1; QString pattern("A %1%2 Composition"); QString name; QSettings s; do { QString suffix; if (10 < (index % 100) && (index % 100) < 14) suffix = tr("th"); switch (index % 10) { case 1: suffix = tr("st"); break; case 2: suffix = tr("nd"); break; case 3: suffix = tr("rd"); break; default: suffix = tr("th"); break; } name = pattern.arg(QString::number(index), suffix); ++index; } while (s.contains(name + QLatin1String("/state"))); return name; } void Introduction::loadExisting() { CompositionButton *button = qobject_cast(sender()); if (!button) return; if (button->editMode()) button->setDeleted(!button->deleted()); else { m_title->setText(button->title()); accept(); } } void Introduction::about() { QDialog *about = new QDialog(0, Qt::Popup); about->setAttribute(Qt::WA_DeleteOnClose); QVBoxLayout *layout = new QVBoxLayout; QLabel *mainText = new QLabel(tr("

Author for Mac v%1

Author helps you write distraction free as the great writers have for centuries. It was inspired by many long conversations with Adam Weiss and was birthed by Jason Donenfeld and ZX2C4 Software.

Visit the Author website for more information. You may address any questions to AuthorApp@zx2c4.com.

(C) Copyright 2011 Jason A. Donenfeld. All Rights Reserved.

").arg(QApplication::applicationVersion())); mainText->setOpenExternalLinks(true); mainText->setTextInteractionFlags(Qt::TextInteractionFlags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, this))); mainText->setWordWrap(true); layout->addWidget(mainText); QFile licenseText(QLatin1String(":/licenses.txt")); licenseText.open(QIODevice::ReadOnly); QPlainTextEdit *licenses = new QPlainTextEdit(licenseText.readAll()); licenseText.close(); QFont font; font.setPointSize(8); licenses->setFont(font); licenses->setReadOnly(true); licenses->setMaximumHeight(100); layout->addWidget(licenses); QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok); buttons->setCenterButtons(style()->styleHint(QStyle::SH_MessageBox_CenterButtons, 0, this)); connect(buttons, SIGNAL(accepted()), about, SLOT(accept())); layout->addWidget(buttons); about->setLayout(layout); about->exec(); } void Introduction::edit() { foreach (CompositionButton *button, m_compositionButtons) button->setEditMode(true); QLayout *layout = m_edit->parentWidget()->layout(); layout->removeWidget(m_edit); m_edit->setParent(0); layout->addWidget(m_editApply); } void Introduction::applyDiscard(QAbstractButton *button) { bool apply = m_editApply->buttonRole(button) == QDialogButtonBox::ApplyRole; QSettings s; foreach (CompositionButton *compositionButton, m_compositionButtons) { if (apply && compositionButton->deleted()) { s.remove(compositionButton->title()); m_compositionButtons.removeOne(compositionButton); compositionButton->deleteLater(); } else if (apply && compositionButton->editedTitle().trimmed().length() > 0 && compositionButton->editedTitle().trimmed() != compositionButton->title().trimmed()) { if (s.childGroups().contains(compositionButton->editedTitle().trimmed())) { compositionButton->setEditMode(false, false); continue; } foreach (const QString &key, s.allKeys()) { if (key.startsWith(compositionButton->title() + QLatin1String("/"))) { QString newKey = key; newKey.replace(compositionButton->title(), compositionButton->editedTitle().trimmed()); s.setValue(newKey, s.value(key)); } } s.remove(compositionButton->title()); compositionButton->setEditMode(false, true); } else compositionButton->setEditMode(false, false); } QLayout *layout = m_editApply->parentWidget()->layout(); layout->removeWidget(m_editApply); m_editApply->setParent(0); layout->addWidget(m_edit); if (m_compositionButtons.isEmpty()) { delete m_existingCompositionBox; m_existingCompositionBox = 0; setFixedWidth(sizeHint().width()); } }