commit 091d5faf141b093406cafd18923e817977c9ec96
Author: d3fault <d3fault@d3fault.net>
Date:   Sun May 28 22:01:00 2017 -0700

    MindDumper: add first launch dir selection wizard. wanted a break from thinking about wasdf so I implemented this ez

diff --git a/.lastModifiedTimestamps b/.lastModifiedTimestamps
index 688bee0..f449273 100644
--- a/.lastModifiedTimestamps
+++ b/.lastModifiedTimestamps
@@ -4094,16 +4094,18 @@ Projects/LossyDirectoryCopier/src/lossydirectorycopiergui.h:1386649739
Projects/LossyDirectoryCopier/src/lossydirectorycopierwidget.cpp:1386987034
Projects/LossyDirectoryCopier/src/lossydirectorycopierwidget.h:1386987034
Projects/LossyDirectoryCopier/src/main.cpp:1386648220
Projects/MindDumper/:1456174632Projects/MindDumper/:1496033126
Projects/MindDumper/design/:1456001533
Projects/MindDumper/design/initial.idea.txt:1456001533
Projects/MindDumper/src/:1495215696
Projects/MindDumper/src/MindDumper.pro:1457146853Projects/MindDumper/src/:1496034000
Projects/MindDumper/src/MindDumper.pro:1496029635
Projects/MindDumper/src/main.cpp:1495215671
Projects/MindDumper/src/minddumpdocument.cpp:1456174998
Projects/MindDumper/src/minddumpdocument.h:1456171263
Projects/MindDumper/src/minddumpermainwindow.cpp:1457471474
Projects/MindDumper/src/minddumpermainwindow.h:1457140576Projects/MindDumper/src/minddumperfirstlaunchdirselector.cpp:1496033461
Projects/MindDumper/src/minddumperfirstlaunchdirselector.h:1496033218
Projects/MindDumper/src/minddumpermainwindow.cpp:1496033186
Projects/MindDumper/src/minddumpermainwindow.h:1496029290
Projects/MouseAndOrMotionViewMaker/:1427380548
Projects/MouseAndOrMotionViewMaker/design/:1396053309
Projects/MouseAndOrMotionViewMaker/design/initial.idea.txt:1396053674
diff --git a/Projects/MindDumper/src/MindDumper.pro b/Projects/MindDumper/src/MindDumper.pro
index c856ea6..5d1c65a 100644
--- a/Projects/MindDumper/src/MindDumper.pro
+++ b/Projects/MindDumper/src/MindDumper.pro
@@ -13,9 +13,12 @@ TEMPLATE = app

SOURCES += main.cpp\
        minddumpermainwindow.cpp \
    minddumpdocument.cpp \
    minddumperfirstlaunchdirselector.cpp

HEADERS  += minddumpermainwindow.h \
    minddumpdocument.h \
    minddumperfirstlaunchdirselector.h

include(../../../GloballySharedClasses/qtsystemsignalhandler.pri)
include(../../../GloballySharedClasses/labellineeditbrowsebutton.pri)
diff --git a/Projects/MindDumper/src/minddumperfirstlaunchdirselector.cpp b/Projects/MindDumper/src/minddumperfirstlaunchdirselector.cpp
new file mode 100644
index 0000000..ca7b8b4
--- /dev/null
+++ b/Projects/MindDumper/src/minddumperfirstlaunchdirselector.cpp
@@ -0,0 +1,61 @@
#include "minddumperfirstlaunchdirselector.h"

#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QStandardPaths>
#include <QPushButton>

#include "labellineeditbrowsebutton.h"

MindDumperFirstLaunchDirSelector::MindDumperFirstLaunchDirSelector(const QString &optionalSeededDirectoryProbablyPassedInAsAppArg, QWidget *parent)
    : QDialog(parent)
{
    bool prepopulateDirWithGuessGoodStartingPoint = optionalSeededDirectoryProbablyPassedInAsAppArg.isEmpty();
    QString mindDumpDirectoryPrepopulatedGuess;
    if(prepopulateDirWithGuessGoodStartingPoint)
    {
        //guesses:"documents" (if writable) -> desktop (dgaf if writable, but must exist) -> "/"
        QString guess = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); //TODOreq: guess. something like ~/ or /var/documents or fuck if I know. let Qt guess for you :). maybe the "desktop" is a good guess (most people don't know how to get to their documents folder (except using a shortcut, so actually yea maybe Documents is better guess dir. hell "Documents" dir could be used as minddump dir for all I care, since I generate filenames so safely))?
        if(guess.isEmpty())
        {
            QStringList desktopLocationsMaybe = QStandardPaths::standardLocations(QStandardPaths::DesktopLocation);
            if(!desktopLocationsMaybe.isEmpty())
            {
                guess = desktopLocationsMaybe.first();
            }
            else
            {
                guess = "/";
            }
        }
        mindDumpDirectoryPrepopulatedGuess = guess;
    }
    else
    {
        mindDumpDirectoryPrepopulatedGuess = optionalSeededDirectoryProbablyPassedInAsAppArg;
    }

    removeTrailingSlashIfPresentButNotIfItsTheOnlyChar(&mindDumpDirectoryPrepopulatedGuess);

    QVBoxLayout *myLayout = new QVBoxLayout();
    QLabel *welcomeText = new QLabel("Welcome. Please choose a MindDumper directory to save your files in. In that directory, your files will be stored in a folder named after the year, and then a subfolder named after the month.\n\nSo for example if you choose: " + mindDumpDirectoryPrepopulatedGuess + "\nThen we will save files like this: " + appendSlashIfNeeded(mindDumpDirectoryPrepopulatedGuess) + "2017/May/example-file.txt"); //TODOoptional: give a 'dynamic' example that uses OS-specific paths. also could factor in mindDumpDirectoryPrepopulatedGuess
    myLayout->addWidget(welcomeText);
    m_MindDumpDirectoryRow = new LabelLineEditBrowseButton("Save files in folder:");
    myLayout->addLayout(m_MindDumpDirectoryRow);
    QHBoxLayout *quitAndOkButtonsRow = new QHBoxLayout();
    QPushButton *quitButton = new QPushButton("&Quit");
    connect(quitButton, &QPushButton::clicked, this, &MindDumperFirstLaunchDirSelector::reject);
    quitAndOkButtonsRow->addWidget(quitButton);
    QPushButton *okButton = new QPushButton("&Ok");
    connect(okButton, &QPushButton::clicked, this, &MindDumperFirstLaunchDirSelector::accept);
    quitAndOkButtonsRow->addWidget(okButton);
    myLayout->addLayout(quitAndOkButtonsRow);
    setLayout(myLayout);

    m_MindDumpDirectoryRow->lineEdit()->setText(mindDumpDirectoryPrepopulatedGuess);
}
QString MindDumperFirstLaunchDirSelector::selectedDir() const
{
    return m_MindDumpDirectoryRow->lineEdit()->text();
}
diff --git a/Projects/MindDumper/src/minddumperfirstlaunchdirselector.h b/Projects/MindDumper/src/minddumperfirstlaunchdirselector.h
new file mode 100644
index 0000000..bb01c68
--- /dev/null
+++ b/Projects/MindDumper/src/minddumperfirstlaunchdirselector.h
@@ -0,0 +1,21 @@
#ifndef MINDDUMPERFIRSTLAUNCHDIRSELECTOR_H
#define MINDDUMPERFIRSTLAUNCHDIRSELECTOR_H

#include <QDialog>

class LabelLineEditBrowseButton;

class MindDumperFirstLaunchDirSelector : public QDialog
{
    Q_OBJECT
public:
    explicit MindDumperFirstLaunchDirSelector(const QString &optionalSeededDirectoryProbablyPassedInAsAppArg = QString(), QWidget *parent = 0);
    QString selectedDir() const;
private:
    static inline void removeTrailingSlashIfPresentButNotIfItsTheOnlyChar(QString *inputString) { int inputStringLength = inputString->length(); if(inputString->endsWith("/") || inputStringLength < 2) return; *inputString = inputString->left(inputStringLength-1); }
    static inline QString appendSlashIfNeeded(const QString &inputString) { if(inputString.endsWith("/")) return inputString; return inputString + "/"; }

    LabelLineEditBrowseButton *m_MindDumpDirectoryRow;
};

#endif // MINDDUMPERFIRSTLAUNCHDIRSELECTOR_H
diff --git a/Projects/MindDumper/src/minddumpermainwindow.cpp b/Projects/MindDumper/src/minddumpermainwindow.cpp
index 12e8c85..dd7e83e 100644
--- a/Projects/MindDumper/src/minddumpermainwindow.cpp
+++ b/Projects/MindDumper/src/minddumpermainwindow.cpp
@@ -13,8 +13,12 @@
#include <QToolBar>

#include "qtsystemsignalhandler.h"
#include "minddumperfirstlaunchdirselector.h"
#include "minddumpdocument.h"

#define MINDDUMP_DIRECTORY_SETTINGS_KEY "minddumpDirectory"
#define FIRST_LAUNCH_SETTINGS_KEY "firstLaunch"

//TODOreq: asterisk in tab title when unsaved, asterisk in window title when any tab unsaved
MindDumperMainWindow::MindDumperMainWindow(QWidget *parent)
    : QMainWindow(parent)
@@ -26,13 +30,51 @@ MindDumperMainWindow::MindDumperMainWindow(QWidget *parent)
    connect(systemSignalHandler, SIGNAL(systemSignalReceived(QtSystemSignal::QtSystemSignalEnum)), this, SLOT(handleSystemSignalInterruptOrTerminateReceived()));
    QStringList argz = qApp->arguments();
    argz.removeFirst(); //app filename

    //TODOreq: arg passed in overrides 'default profile minddump directory', or even just plainly 'minddumpDirectory' (before 'profiles' gets implemented)
    if(argz.size() !=> 1)
    {
        QMessageBox::critical(this, tr("Critical Error!"), tr("The firsttr("There can only be one (optional) argument provided to this application must be the(the path of your minddump directory.directory). Quitting"));
        doQueuedClose();
        return;
    }
    else if(argz.size() == 1)
    {
        m_MindDumpDirectoryWithSlashAppended = appendSlashIfNeeded(argz.takeFirst());
    }

    QCoreApplication::setOrganizationName("MindDumperOrganization");
    QCoreApplication::setOrganizationDomain("MindDumperDomain");
    QCoreApplication::setApplicationName("MindDumper");

    QSettings settings;
    QString minddumpDirectoryInSettings = settings.value(MINDDUMP_DIRECTORY_SETTINGS_KEY).toString();
    bool firstLaunch = settings.value(FIRST_LAUNCH_SETTINGS_KEY, true).toBool();
    bool minddumpDirIsInSettings = !(minddumpDirectoryInSettings.trimmed().isEmpty());
    if(firstLaunch || (!minddumpDirIsInSettings))
    {
        //TODOreq: show welcome/browse-for-directory widget
        //TODOreq: they might have supplied a dir as an app arg, so prepopulate the line edit with that to save them time
        settings.setValue(FIRST_LAUNCH_SETTINGS_KEY, false);
        MindDumperFirstLaunchDirSelector dirSelector(m_MindDumpDirectoryWithSlashAppended);
        dirSelector.setModal(true);
        dirSelector.setWindowModality(Qt::ApplicationModal);
        int dialogResultCode = dirSelector.exec();
        if(dialogResultCode != QDialog::Accepted)
        {
            doQueuedClose();
            return;
        }
        m_MindDumpDirectoryWithSlashAppended = appendSlashIfNeeded(dirSelector.selectedDir());
    }
    else if(minddumpDirIsInSettings)
    {
        if(m_MindDumpDirectoryWithSlashAppended.isEmpty()) //it might have been already set via app arg above
        {
            m_MindDumpDirectoryWithSlashAppended = appendSlashIfNeeded(minddumpDirectoryInSettings);
        }
    }

    QFileInfo fileInfo(m_MindDumpDirectoryWithSlashAppended);
    if(!fileInfo.isDir())
    {
@@ -46,11 +88,8 @@ MindDumperMainWindow::MindDumperMainWindow(QWidget *parent)
        doQueuedClose();
        return;
    }
    settings.setValue(MINDDUMP_DIRECTORY_SETTINGS_KEY, m_MindDumpDirectoryWithSlashAppended);

    QCoreApplication::setOrganizationName("MindDumperOrganization");
    QCoreApplication::setOrganizationDomain("MindDumperDomain");
    QCoreApplication::setApplicationName("MindDumper");
    QSettings settings;
    restoreGeometry(settings.value("geometry").toByteArray());
    //restoreState(settings.value("windowState").toByteArray());

@@ -373,5 +412,6 @@ void MindDumperMainWindow::handleSystemSignalInterruptOrTerminateReceived()
}
void MindDumperMainWindow::doQueuedClose()
{
    //TODOmb: this->setEnabled(false);
    QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection);
}