Skip to content

Commit

Permalink
Merge pull request #312 from splintermind/auto-connect
Browse files Browse the repository at this point in the history
Auto connect
  • Loading branch information
splintermind committed Jul 6, 2016
2 parents fcd6393 + 194de2c commit 0f00a17
Show file tree
Hide file tree
Showing 11 changed files with 229 additions and 168 deletions.
5 changes: 3 additions & 2 deletions inc/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public slots:
void read_dwarves();
void new_pending_changes(int);
void new_creatures_count(int, int, int, QString);
void lost_df_connection();
void lost_df_connection(bool show_dialog = true);

//settings
void set_group_by(int);
Expand Down Expand Up @@ -150,7 +150,7 @@ public slots:
void refresh_active_scripts();
void clear_filter();

void show_connection_err(QStringList msg);
void show_dc_dialog(QStringList msg);

private:
DFInstance *m_df;
Expand Down Expand Up @@ -179,6 +179,7 @@ public slots:
QAction *m_act_sep_optimize;
QAction *m_act_btn_optimize; //this is required in addition to the button to allow easy visibility toggling
QToolButton *m_btn_optimize;
QTimer *m_retry_connection;

Updater *m_updater;
NotifierWidget *m_notifier;
Expand Down
6 changes: 3 additions & 3 deletions inc/models/dwarfmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ THE SOFTWARE.

#include <QStandardItemModel>
#include "columntypes.h"
#include "dfinstance.h"

class Dwarf;
class DFInstance;
class DwarfModel;
class DwarfModelProxy;
class GridView;
Expand Down Expand Up @@ -109,7 +109,7 @@ class DwarfModel : public QStandardItemModel {

DwarfModel(QObject *parent = 0);
virtual ~DwarfModel();
void set_instance(DFInstance *df) {m_df = df;}
void set_instance(DFInstance *df) {m_df = QPointer<DFInstance>(df);}
void set_grid_view(GridView *v) {m_gridview = v;}
GridView * current_grid_view() {return m_gridview;}
void clear_all(bool clr_pend); // reset everything to normal
Expand Down Expand Up @@ -159,7 +159,7 @@ public slots:
void read_settings();

private:
DFInstance *m_df;
QPointer<DFInstance> m_df;
QHash<int, Dwarf*> m_dwarves;
QMap<QString, QVector<Dwarf*> > m_grouped_dwarves;
GROUP_BY m_group_by;
Expand Down
13 changes: 13 additions & 0 deletions inc/optionsmenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ THE SOFTWARE.
#include <QDialog>
#include "uberdelegate.h"

#define MSG_WARN_READ "$WARN_READ"
#define MSG_LIVESTOCK "$LIVESTOCK"

namespace Ui { class OptionsMenu; }
class CustomColor;
class QLabel;
Expand Down Expand Up @@ -74,6 +77,15 @@ class OptionsMenu : public QDialog {
QPair<QFont,QFont> m_tooltip_font;
QPair<QFont,QFont> m_main_font;

static const QStringList m_msg_vars;

static const QString get_message(const QString &key) {
QMap<QString,QString> m;
m[MSG_WARN_READ] = tr("<font color=red><b>This change will not take effect until the next full read!</b></font>");
m[MSG_LIVESTOCK] = tr("<b>This is always enabled for livestock.</b>");
return m.value(key,"");
}

private slots:
void tooltip_skills_toggled(bool);
void tooltip_roles_toggled(bool);
Expand All @@ -85,5 +97,6 @@ private slots:
void color_changed(const QString &, const QColor &);
//! emitted when the options menu "ok" button is hit
void settings_changed();

};
#endif
1 change: 1 addition & 0 deletions resources.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
<file alias="img/exclamation--frame.png">resources/img/exclamation--frame.png</file>
<file alias="img/plug--arrow.png">resources/img/plug--arrow.png</file>
<file alias="img/plug-connect.png">resources/img/plug-connect.png</file>
<file alias="img/arrow-circle.png">resources/img/arrow-circle.png</file>
</qresource>
<qresource prefix="/happiness">
<file alias="Ecstatic.png">resources/img/Ecstatic.png</file>
Expand Down
Binary file added resources/img/arrow-circle.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 changes: 41 additions & 28 deletions src/dfinstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,10 @@ DFInstance::DFInstance(QObject* parent)
}

// if no memory layouts were found that's a critical error
// continue though, as a layout may be automatically downloaded
if (m_memory_layouts.size() < 1) {
LOGE << "No valid memory layouts found in the following directories..."
<< QDir::searchPaths("share");
qApp->exit(ERROR_NO_VALID_LAYOUTS);
LOGW << "No valid layouts found in the following directories:" << QDir::searchPaths("share");
//qApp->exit(ERROR_NO_VALID_LAYOUTS);
}

if (!QTextCodec::codecForName("IBM437"))
Expand Down Expand Up @@ -1107,22 +1107,29 @@ MemoryLayout *DFInstance::find_memory_layout(QString git_sha){
}

bool DFInstance::add_new_layout(const QString & filename, const QString data, QString &result_msg) {
QFileInfo file_info(QDir(QString("share/memory_layouts/%1").arg(LAYOUT_SUBDIR)), filename);
QString file_path = file_info.absoluteFilePath();
bool ok = false;

QFile file(file_path);
if(file.exists()){
result_msg = tr("Layout file %1 already exist!").arg(file_path);
QFileInfo file_info;
QDir layouts_dir = QDir(QString("share/memory_layouts/%1").arg(LAYOUT_SUBDIR));
if(!layouts_dir.exists() && !layouts_dir.mkpath(layouts_dir.absolutePath())){
LOGE << "Failed to create directory path:" << layouts_dir.absolutePath();
result_msg = tr("Failed to create directory %1").arg(layouts_dir.absolutePath());
}else{
LOGI << "Creating new layout file:" << file_path;
if(!file.open(QIODevice::WriteOnly)) {
result_msg = tr("Failed to create layout file %1").arg(file_path);
file_info = QFileInfo(layouts_dir, filename);
QString file_path = file_info.absoluteFilePath();
QFile file(file_path);
if(file.exists()){
result_msg = tr("Layout file %1 already exist!").arg(file_path);
}else{
QTextStream layout(&file);
layout << data;
file.close();
ok = true;
LOGI << "Creating new layout file:" << file_path;
if(!file.open(QIODevice::WriteOnly)) {
result_msg = tr("Failed to create layout file %1").arg(file_path);
}else{
QTextStream layout(&file);
layout << data;
file.close();
ok = true;
}
}
}

Expand Down Expand Up @@ -1157,20 +1164,26 @@ const QStringList DFInstance::status_err_msg(){
break;
case DFS_CONNECTED:
{
QString supported_vers;
QList<MemoryLayout *> layouts = m_memory_layouts.values();
qSort(layouts);

foreach(MemoryLayout * l, layouts) {
supported_vers.append(
QString("%1 (%2)\n")
.arg(l->game_version()).arg(l->checksum()));
}
if(m_memory_layouts.count() < 1){
ret << tr("No Layouts Found");
ret << tr("No valid memory layouts could be found to attempt connection to Dwarf Fortress.");
ret << tr("View the details below for the directories checked.");
ret << QDir::searchPaths("share").join("\n");
}else{
QStringList supported_vers;
QList<MemoryLayout *> layouts = m_memory_layouts.values();
qSort(layouts);

ret << tr("Unidentified Game Version");
ret << tr("I'm sorry but I don't know how to talk to this version of Dwarf Fortress!");
ret << tr("Checksum: %1").arg(m_df_checksum);
ret << tr("Supported Versions:\n%1").arg(supported_vers);
foreach(MemoryLayout * l, layouts) {
supported_vers.append(
QString("%1 (%2)").arg(l->game_version()).arg(l->checksum()));
}

ret << tr("Unidentified Game Version");
ret << tr("I'm sorry but I don't know how to talk to this version of Dwarf Fortress!");
ret << tr("Checksum: %1").arg(m_df_checksum);
ret << tr("Supported Versions:\n%1").arg(supported_vers.join("\n"));
}
}
break;
case DFS_LAYOUT_OK:
Expand Down
96 changes: 69 additions & 27 deletions src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ THE SOFTWARE.
#include <QTime>
#include <QPainter>
#include <QUrl>
#include <QTimer>

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
Expand All @@ -97,6 +98,7 @@ MainWindow::MainWindow(QWidget *parent)
, m_toolbar_configured(false)
, m_act_sep_optimize(0)
, m_btn_optimize(0)
, m_retry_connection(0)
{
ui->setupUi(this);

Expand Down Expand Up @@ -211,7 +213,6 @@ MainWindow::MainWindow(QWidget *parent)
//DT then emits a second signal, ensuring that any updates to data is done before signalling other objects
//the view manager is signalled this way, to ensure that the order of signals is preserved
connect(DT,SIGNAL(connected()),m_view_manager,SLOT(rebuild_global_sort_keys()));
connect(m_updater,SIGNAL(notify(NotifierWidget::notify_info)),m_notifier,SLOT(add_notification(NotifierWidget::notify_info)));

m_settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, COMPANY, PRODUCT, this);

Expand Down Expand Up @@ -385,6 +386,21 @@ void MainWindow::closeEvent(QCloseEvent *evt) {
}

void MainWindow::connect_to_df() {
bool show_dc_dialog = true;
if(m_retry_connection){
if(m_retry_connection->isActive()){
m_retry_connection->stop();
}
show_dc_dialog = (sender() != m_retry_connection);
}

//don't spam notifications on auto-retry connections
if(!show_dc_dialog){
disconnect(m_updater,SIGNAL(notify(NotifierWidget::notify_info)),m_notifier,SLOT(add_notification(NotifierWidget::notify_info)));
}else{
connect(m_updater,SIGNAL(notify(NotifierWidget::notify_info)),m_notifier,SLOT(add_notification(NotifierWidget::notify_info)),Qt::UniqueConnection);
}

LOGI << "attempting connection to running DF game";
if (m_df) {
LOGI << "already connected, disconnecting";
Expand Down Expand Up @@ -433,10 +449,10 @@ void MainWindow::connect_to_df() {
read_dwarves();
}
}else{
lost_df_connection();
lost_df_connection(show_dc_dialog);
}
}else{
lost_df_connection();
lost_df_connection(show_dc_dialog);
}
}

Expand All @@ -445,30 +461,12 @@ void MainWindow::set_status_message(QString msg, QString tooltip_msg){
m_lbl_status->setToolTip(tr("<span>%1</span>").arg(tooltip_msg));
}

void MainWindow::show_connection_err(QStringList msg){
if(!msg.isEmpty()){
LOGE << msg;
set_status_message(msg.value(0),"");
if(DT->user_settings()->value("options/alert_on_lost_connection", true).toBool()){
QMessageBox mb(this);
mb.setIcon(QMessageBox::Warning);
mb.setStandardButtons(QMessageBox::Ok);
mb.setWindowTitle(msg.at(0));
if(!msg.value(1).isEmpty())
mb.setText(msg.at(1));
QString desc = msg.value(2);
if(!desc.isEmpty())
desc.append("<br><br>");
mb.setInformativeText(desc.append(tr("Please re-connect when Dwarf Fortress has been started and a fort has been loaded.")));
if(!msg.value(3).isEmpty())
mb.setDetailedText(msg.at(3));
mb.exec();
}
}
}

void MainWindow::lost_df_connection() {
void MainWindow::lost_df_connection(bool show_dialog) {
LOGW << "lost connection to DF";
if(m_retry_connection && m_retry_connection->isActive()){
//stop the timer if it's running in case this slot was called directly
m_retry_connection->stop();
}
emit lostConnection();
QStringList err_msg;
if (m_df) {
Expand All @@ -483,7 +481,48 @@ void MainWindow::lost_df_connection() {
err_msg << tr("Startup Failed");
err_msg << tr("Dwarf Therapist failed to startup!");
}
show_connection_err(err_msg);

//display the error details to the user
if(!err_msg.isEmpty()){
LOGE << err_msg;
set_status_message(err_msg.value(0),"");
if(show_dialog && DT->user_settings()->value("options/alert_on_lost_connection", true).toBool()){
show_dc_dialog(err_msg);
}
}

//start the retry connection timer
if(DT->user_settings()->value("options/auto_connect", false).toBool()){
if(!m_df || m_df->status() == DFInstance::DFS_DISCONNECTED){
if(!m_retry_connection){
m_retry_connection = new QTimer(this);
m_retry_connection->setInterval(5000);
connect(m_retry_connection,SIGNAL(timeout()),this,SLOT(connect_to_df()),Qt::UniqueConnection);
}
set_progress_message(tr("Attempting to connect to Dwarf Fortress..."));
m_retry_connection->start();
ui->act_connect_to_DF->setIcon(QIcon(":/img/arrow-circle.png"));
ui->act_connect_to_DF->setToolTip(tr("Automatically retrying connection every %1s.<br><br>Click to retry immediately.")
.arg(QString::number(m_retry_connection->interval()/1000)));
ui->act_connect_to_DF->setText(tr("Auto.."));
}
}
}

void MainWindow::show_dc_dialog(QStringList msg){
QMessageBox mb(this);
mb.setIcon(QMessageBox::Warning);
mb.setStandardButtons(QMessageBox::Ok);
mb.setWindowTitle(msg.at(0));
if(!msg.value(1).isEmpty())
mb.setText(msg.at(1));
QString desc = msg.value(2);
if(!desc.isEmpty())
desc.append("<br><br>");
mb.setInformativeText(desc.append(tr("Please re-connect when Dwarf Fortress has been started and a fort has been loaded.")));
if(!msg.value(3).isEmpty())
mb.setDetailedText(msg.at(3));
mb.exec();
}

void MainWindow::read_dwarves() {
Expand Down Expand Up @@ -653,12 +692,15 @@ void MainWindow::apply_filter(QModelIndex idx){
void MainWindow::set_interface_enabled(bool enabled) {
ui->act_connect_to_DF->setEnabled(!enabled);
if(enabled){
ui->act_connect_to_DF->setText(tr("Connected"));
ui->act_connect_to_DF->setIcon(QIcon(":/img/plug-connect.png"));
ui->act_connect_to_DF->setToolTip(tr("A connection to Dwarf Fortress has been established!"));
}else{
ui->act_connect_to_DF->setText(tr("Connect"));
ui->act_connect_to_DF->setIcon(QIcon(":/img/plug--arrow.png"));
ui->act_connect_to_DF->setToolTip(tr("Attempt connecting to a running copy of Dwarf Fortress (CTRL+SHIFT+C)"));
}
ui->act_connect_to_DF->setStatusTip(ui->act_connect_to_DF->toolTip());
ui->act_read_dwarves->setEnabled(enabled);
ui->act_expand_all->setEnabled(enabled);
ui->act_collapse_all->setEnabled(enabled);
Expand Down
6 changes: 3 additions & 3 deletions src/models/dwarfmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ void DwarfModel::build_rows() {

if(only_animals)
race_name = tr("Animals");
else if(m_df){
else if(!m_df.isNull()){
Race* r = m_df->get_race(m_df->dwarf_race_id());
if(r)
race_name = r->plural_name();
Expand Down Expand Up @@ -778,7 +778,7 @@ void DwarfModel::cell_activated(const QModelIndex &idx, DwarfModelProxy *proxy)
void DwarfModel::set_group_by(int group_by) {
LOGI << "group_by now set to" << group_by << " for view " << current_grid_view()->name();
m_group_by = static_cast<GROUP_BY>(group_by);
if(m_df){
if(!m_df.isNull()){
QTime t;
t.start();
build_rows();
Expand All @@ -799,7 +799,7 @@ void DwarfModel::calculate_pending() {
}

void DwarfModel::clear_pending() {
if(!m_df){
if(m_df.isNull()){
return;
}
//clear squads before we refresh dwarf data
Expand Down

0 comments on commit 0f00a17

Please sign in to comment.