Save chats and tabs in new settings system

This commit is contained in:
Rasmus Karlsson 2017-12-22 14:44:31 +01:00
parent 42749538a7
commit d8c01ce374
14 changed files with 187 additions and 293 deletions

View file

@ -27,13 +27,11 @@ Application::Application()
// XXX // XXX
SettingsManager::getInstance().updateWordTypeMask(); SettingsManager::getInstance().updateWordTypeMask();
this->windowManager.load();
} }
Application::~Application() Application::~Application()
{ {
this->windowManager.save(); this->save();
chatterino::SettingsManager::getInstance().save(); chatterino::SettingsManager::getInstance().save();
} }
@ -49,4 +47,9 @@ int Application::run(QApplication &qtApp)
return qtApp.exec(); return qtApp.exec();
} }
void Application::save()
{
this->windowManager.save();
}
} // namespace chatterino } // namespace chatterino

View file

@ -25,6 +25,9 @@ public:
Resources resources; Resources resources;
ChannelManager channelManager; ChannelManager channelManager;
IrcManager ircManager; IrcManager ircManager;
private:
void save();
}; };
} // namespace chatterino } // namespace chatterino

View file

@ -1,6 +1,9 @@
#include "widgets/helper/notebooktab.hpp" #include "widgets/helper/notebooktab.hpp"
#include "colorscheme.hpp" #include "colorscheme.hpp"
#include "common.hpp"
#include "debug/log.hpp"
#include "settingsmanager.hpp" #include "settingsmanager.hpp"
#include "util/helpers.hpp"
#include "widgets/notebook.hpp" #include "widgets/notebook.hpp"
#include "widgets/textinputdialog.hpp" #include "widgets/textinputdialog.hpp"
@ -11,10 +14,13 @@
namespace chatterino { namespace chatterino {
namespace widgets { namespace widgets {
NotebookTab::NotebookTab(Notebook *_notebook) NotebookTab::NotebookTab(Notebook *_notebook, const std::string &settingPrefix)
: BaseWidget(_notebook) : BaseWidget(_notebook)
, settingRoot(fS("{}/tab", settingPrefix))
, positionChangedAnimation(this, "pos") , positionChangedAnimation(this, "pos")
, notebook(_notebook) , notebook(_notebook)
, title(fS("{}/title", this->settingRoot), "")
, useDefaultBehaviour(fS("{}/useDefaultBehaviour", this->settingRoot), true)
, menu(this) , menu(this)
{ {
this->calcSize(); this->calcSize();
@ -49,26 +55,29 @@ NotebookTab::NotebookTab(Notebook *_notebook)
} }
}); });
this->menu.addAction("Close", [=]() { QAction *enableHighlightsOnNewMessageAction =
this->notebook->removePage(this->page); new QAction("Enable highlights on new message", &this->menu);
enableHighlightsOnNewMessageAction->setCheckable(true);
qDebug() << "lmoa"; this->menu.addAction("Close", [=]() { this->notebook->removePage(this->page); });
});
this->menu.addAction("Enable highlights on new message", []() { this->menu.addAction(enableHighlightsOnNewMessageAction);
qDebug() << "TODO: Implement"; //
connect(enableHighlightsOnNewMessageAction, &QAction::toggled, [this](bool newValue) {
debug::Log("New value is {}", newValue); //
}); });
} }
void NotebookTab::calcSize() void NotebookTab::calcSize()
{ {
float scale = getDpiMultiplier(); float scale = getDpiMultiplier();
QString qTitle(qS(this->title));
if (SettingsManager::getInstance().hideTabX) { if (SettingsManager::getInstance().hideTabX) {
this->resize(static_cast<int>((fontMetrics().width(title) + 16) * scale), this->resize(static_cast<int>((fontMetrics().width(qTitle) + 16) * scale),
static_cast<int>(24 * scale)); static_cast<int>(24 * scale));
} else { } else {
this->resize(static_cast<int>((fontMetrics().width(title) + 8 + 24) * scale), this->resize(static_cast<int>((fontMetrics().width(qTitle) + 8 + 24) * scale),
static_cast<int>(24 * scale)); static_cast<int>(24 * scale));
} }
@ -77,14 +86,14 @@ void NotebookTab::calcSize()
} }
} }
const QString &NotebookTab::getTitle() const QString NotebookTab::getTitle() const
{ {
return title; return qS(this->title);
} }
void NotebookTab::setTitle(const QString &newTitle) void NotebookTab::setTitle(const QString &newTitle)
{ {
this->title = newTitle; this->title = newTitle.toStdString();
this->calcSize(); this->calcSize();
} }
@ -182,7 +191,7 @@ void NotebookTab::paintEvent(QPaintEvent *)
int rectW = (SettingsManager::getInstance().hideTabX ? 0 : static_cast<int>(16) * scale); int rectW = (SettingsManager::getInstance().hideTabX ? 0 : static_cast<int>(16) * scale);
QRect rect(0, 0, this->width() - rectW, this->height()); QRect rect(0, 0, this->width() - rectW, this->height());
painter.drawText(rect, title, QTextOption(Qt::AlignCenter)); painter.drawText(rect, this->getTitle(), QTextOption(Qt::AlignCenter));
if (!SettingsManager::getInstance().hideTabX && (mouseOver || selected)) { if (!SettingsManager::getInstance().hideTabX && (mouseOver || selected)) {
QRect xRect = this->getXRect(); QRect xRect = this->getXRect();
@ -282,33 +291,5 @@ void NotebookTab::mouseMoveEvent(QMouseEvent *event)
} }
} }
void NotebookTab::load(const boost::property_tree::ptree &tree)
{
// Load tab title
try {
QString newTitle = QString::fromStdString(tree.get<std::string>("title"));
if (newTitle.isEmpty()) {
this->useDefaultBehaviour = true;
} else {
this->setTitle(newTitle);
this->useDefaultBehaviour = false;
}
} catch (boost::property_tree::ptree_error) {
}
}
boost::property_tree::ptree NotebookTab::save()
{
boost::property_tree::ptree tree;
if (this->useDefaultBehaviour) {
tree.put("title", "");
} else {
tree.put("title", this->getTitle().toStdString());
}
return tree;
}
} // namespace widgets } // namespace widgets
} // namespace chatterino } // namespace chatterino

View file

@ -4,7 +4,7 @@
#include <QMenu> #include <QMenu>
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include <boost/property_tree/ptree.hpp> #include <pajlada/settings/setting.hpp>
#include <pajlada/signals/connection.hpp> #include <pajlada/signals/connection.hpp>
namespace chatterino { namespace chatterino {
@ -20,16 +20,18 @@ class NotebookTab : public BaseWidget
{ {
Q_OBJECT Q_OBJECT
std::string settingRoot;
public: public:
enum HighlightStyle { HighlightNone, HighlightHighlighted, HighlightNewMessage }; enum HighlightStyle { HighlightNone, HighlightHighlighted, HighlightNewMessage };
explicit NotebookTab(Notebook *_notebook); explicit NotebookTab(Notebook *_notebook, const std::string &settingPrefix);
void calcSize(); void calcSize();
SplitContainer *page; SplitContainer *page;
const QString &getTitle() const; QString getTitle() const;
void setTitle(const QString &newTitle); void setTitle(const QString &newTitle);
bool isSelected() const; bool isSelected() const;
void setSelected(bool value); void setSelected(bool value);
@ -63,10 +65,10 @@ private:
Notebook *notebook; Notebook *notebook;
QString title; pajlada::Settings::Setting<std::string> title;
public: public:
bool useDefaultBehaviour = true; pajlada::Settings::Setting<bool> useDefaultBehaviour;
private: private:
bool selected = false; bool selected = false;
@ -85,10 +87,6 @@ private:
return QRect(this->width() - static_cast<int>(20 * scale), static_cast<int>(4 * scale), return QRect(this->width() - static_cast<int>(20 * scale), static_cast<int>(4 * scale),
static_cast<int>(16 * scale), static_cast<int>(16 * scale)); static_cast<int>(16 * scale), static_cast<int>(16 * scale));
} }
public:
void load(const boost::property_tree::ptree &tree);
boost::property_tree::ptree save();
}; };
} // namespace widgets } // namespace widgets

View file

@ -15,14 +15,17 @@
#include <QList> #include <QList>
#include <QShortcut> #include <QShortcut>
#include <QStandardPaths> #include <QStandardPaths>
#include <QUuid>
#include <QWidget> #include <QWidget>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
namespace chatterino { namespace chatterino {
namespace widgets { namespace widgets {
Notebook::Notebook(ChannelManager &_channelManager, Window *parent, bool _showButtons) Notebook::Notebook(ChannelManager &_channelManager, Window *parent, bool _showButtons,
const std::string &settingPrefix)
: BaseWidget(parent) : BaseWidget(parent)
, settingRoot(fS("{}/notebook", settingPrefix))
, channelManager(_channelManager) , channelManager(_channelManager)
, addButton(this) , addButton(this)
, settingsButton(this) , settingsButton(this)
@ -42,12 +45,21 @@ Notebook::Notebook(ChannelManager &_channelManager, Window *parent, bool _showBu
settingsManager.hidePreferencesButton.connectSimple([this](auto) { this->performLayout(); }); settingsManager.hidePreferencesButton.connectSimple([this](auto) { this->performLayout(); });
settingsManager.hideUserButton.connectSimple([this](auto) { this->performLayout(); }); settingsManager.hideUserButton.connectSimple([this](auto) { this->performLayout(); });
this->loadContainers();
} }
SplitContainer *Notebook::addPage(bool select) SplitContainer *Notebook::addNewPage()
{ {
auto tab = new NotebookTab(this); return this->addPage(CreateUUID().toStdString(), true);
auto page = new SplitContainer(this->channelManager, this, tab); }
SplitContainer *Notebook::addPage(const std::string &uuid, bool select)
{
std::string key = fS("{}/containers/{}", this->settingRoot, uuid);
auto tab = new NotebookTab(this, key);
auto page = new SplitContainer(this->channelManager, this, tab, key);
tab->show(); tab->show();
@ -80,7 +92,7 @@ void Notebook::removePage(SplitContainer *page)
this->pages.removeOne(page); this->pages.removeOne(page);
if (this->pages.size() == 0) { if (this->pages.size() == 0) {
addPage(); this->addNewPage();
} }
this->performLayout(); this->performLayout();
@ -253,54 +265,25 @@ void Notebook::usersButtonClicked()
void Notebook::addPageButtonClicked() void Notebook::addPageButtonClicked()
{ {
QTimer::singleShot(80, [this] { this->addPage(true); }); QTimer::singleShot(80, [this] { this->addNewPage(); });
} }
void Notebook::load(const boost::property_tree::ptree &tree) void Notebook::loadContainers()
{ {
// Read a list of tabs std::string containersKey = fS("{}/containers", this->settingRoot);
try {
BOOST_FOREACH (const boost::property_tree::ptree::value_type &v, tree.get_child("tabs.")) {
bool select = v.second.get<bool>("selected", false);
auto page = addPage(select); auto keys = pajlada::Settings::SettingManager::getObjectKeys(containersKey);
auto tab = page->getTab();
tab->load(v.second);
page->load(v.second);
}
} catch (boost::property_tree::ptree_error &) {
// can't read tabs
}
if (this->pages.size() == 0) { for (const std::string &key : keys) {
// No pages saved, show default stuff this->addPage(key);
loadDefaults();
} }
} }
void Notebook::save(boost::property_tree::ptree &tree) void Notebook::save()
{ {
boost::property_tree::ptree tabs;
// Iterate through all tabs and add them to our tabs property thing
for (const auto &page : this->pages) { for (const auto &page : this->pages) {
boost::property_tree::ptree pTab = page->getTab()->save(); page->save();
boost::property_tree::ptree pChats = page->save();
if (pChats.size() > 0) {
pTab.add_child("columns", pChats);
} }
tabs.push_back(std::make_pair("", pTab));
}
tree.add_child("tabs", tabs);
}
void Notebook::loadDefaults()
{
addPage();
} }
} // namespace widgets } // namespace widgets

View file

@ -7,7 +7,6 @@
#include <QList> #include <QList>
#include <QWidget> #include <QWidget>
#include <boost/property_tree/ptree.hpp>
namespace chatterino { namespace chatterino {
@ -21,12 +20,16 @@ class Notebook : public BaseWidget
{ {
Q_OBJECT Q_OBJECT
std::string settingRoot;
public: public:
enum HighlightType { none, highlighted, newMessage }; enum HighlightType { none, highlighted, newMessage };
explicit Notebook(ChannelManager &_channelManager, Window *parent, bool showButtons); explicit Notebook(ChannelManager &_channelManager, Window *parent, bool _showButtons,
const std::string &settingPrefix);
SplitContainer *addPage(bool select = false); SplitContainer *addNewPage();
SplitContainer *addPage(const std::string &uuid, bool select = false);
void removePage(SplitContainer *page); void removePage(SplitContainer *page);
void select(SplitContainer *page); void select(SplitContainer *page);
@ -69,10 +72,10 @@ private:
bool showButtons; bool showButtons;
void loadContainers();
public: public:
void load(const boost::property_tree::ptree &tree); void save();
void save(boost::property_tree::ptree &tree);
void loadDefaults();
}; };
} // namespace widgets } // namespace widgets

View file

@ -47,9 +47,11 @@ inline void ezShortcut(Split *w, const char *key, T t)
static int index = 0; static int index = 0;
Split::Split(ChannelManager &_channelManager, SplitContainer *parent) Split::Split(ChannelManager &_channelManager, SplitContainer *parent, const std::string &_uuid)
: BaseWidget(parent) : BaseWidget(parent)
, channelName("/chatWidgets/" + std::to_string(index++) + "/channelName") , uuid(_uuid)
, settingRoot(fS("/splits/{}", this->uuid))
, channelName(fS("{}/channelName", this->settingRoot))
, parentPage(*parent) , parentPage(*parent)
, channelManager(_channelManager) , channelManager(_channelManager)
, channel(_channelManager.emptyChannel) , channel(_channelManager.emptyChannel)
@ -123,6 +125,11 @@ Split::~Split()
this->channelNameUpdated(""); this->channelNameUpdated("");
} }
const std::string &Split::getUUID() const
{
return this->uuid;
}
std::shared_ptr<Channel> Split::getChannel() const std::shared_ptr<Channel> Split::getChannel() const
{ {
return this->channel; return this->channel;
@ -234,24 +241,6 @@ void Split::paintEvent(QPaintEvent *)
painter.fillRect(this->rect(), this->colorScheme.ChatBackground); painter.fillRect(this->rect(), this->colorScheme.ChatBackground);
} }
void Split::load(const boost::property_tree::ptree &tree)
{
// load tab text
try {
this->channelName = tree.get<std::string>("channelName");
} catch (boost::property_tree::ptree_error) {
}
}
boost::property_tree::ptree Split::save()
{
boost::property_tree::ptree tree;
tree.put("channelName", this->channelName.getValue());
return tree;
}
/// Slots /// Slots
void Split::doAddSplit() void Split::doAddSplit()
{ {
@ -280,8 +269,8 @@ void Split::doPopup()
Window &window = WindowManager::instance->createWindow(); Window &window = WindowManager::instance->createWindow();
Split *split = new Split(this->channelManager, Split *split = new Split(this->channelManager,
static_cast<SplitContainer *>(window.getNotebook().getSelectedPage())); static_cast<SplitContainer *>(window.getNotebook().getSelectedPage()),
split->channelName = this->channelName.getValue(); this->uuid);
window.getNotebook().getSelectedPage()->addToLayout(split); window.getNotebook().getSelectedPage()->addToLayout(split);

View file

@ -15,7 +15,6 @@
#include <QShortcut> #include <QShortcut>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QWidget> #include <QWidget>
#include <boost/property_tree/ptree.hpp>
#include <boost/signals2/connection.hpp> #include <boost/signals2/connection.hpp>
namespace chatterino { namespace chatterino {
@ -43,14 +42,18 @@ class Split : public BaseWidget
Q_OBJECT Q_OBJECT
const std::string uuid;
const std::string settingRoot;
public: public:
Split(ChannelManager &_channelManager, SplitContainer *parent); Split(ChannelManager &_channelManager, SplitContainer *parent, const std::string &_uuid);
~Split(); ~Split();
ChannelManager &channelManager; ChannelManager &channelManager;
pajlada::Settings::Setting<std::string> channelName; pajlada::Settings::Setting<std::string> channelName;
boost::signals2::signal<void()> channelChanged; boost::signals2::signal<void()> channelChanged;
const std::string &getUUID() const;
std::shared_ptr<Channel> getChannel() const; std::shared_ptr<Channel> getChannel() const;
std::shared_ptr<Channel> &getChannelRef(); std::shared_ptr<Channel> &getChannelRef();
void setFlexSizeX(double x); void setFlexSizeX(double x);
@ -63,8 +66,6 @@ public:
bool hasFocus() const; bool hasFocus() const;
void layoutMessages(); void layoutMessages();
void updateGifEmotes(); void updateGifEmotes();
void load(const boost::property_tree::ptree &tree);
boost::property_tree::ptree save();
protected: protected:
virtual void paintEvent(QPaintEvent *) override; virtual void paintEvent(QPaintEvent *) override;

View file

@ -1,5 +1,6 @@
#include "widgets/splitcontainer.hpp" #include "widgets/splitcontainer.hpp"
#include "colorscheme.hpp" #include "colorscheme.hpp"
#include "util/helpers.hpp"
#include "widgets/helper/notebooktab.hpp" #include "widgets/helper/notebooktab.hpp"
#include "widgets/notebook.hpp" #include "widgets/notebook.hpp"
#include "widgets/split.hpp" #include "widgets/split.hpp"
@ -23,8 +24,12 @@ bool SplitContainer::isDraggingSplit = false;
Split *SplitContainer::draggingSplit = nullptr; Split *SplitContainer::draggingSplit = nullptr;
std::pair<int, int> SplitContainer::dropPosition = std::pair<int, int>(-1, -1); std::pair<int, int> SplitContainer::dropPosition = std::pair<int, int>(-1, -1);
SplitContainer::SplitContainer(ChannelManager &_channelManager, Notebook *parent, NotebookTab *_tab) SplitContainer::SplitContainer(ChannelManager &_channelManager, Notebook *parent, NotebookTab *_tab,
const std::string &_settingPrefix)
: BaseWidget(parent->colorScheme, parent) : BaseWidget(parent->colorScheme, parent)
, settingPrefix(_settingPrefix)
, settingRoot(fS("{}", this->settingPrefix))
, chats(fS("{}/chats", this->settingRoot))
, channelManager(_channelManager) , channelManager(_channelManager)
, tab(_tab) , tab(_tab)
, dropPreview(this) , dropPreview(this)
@ -44,6 +49,8 @@ SplitContainer::SplitContainer(ChannelManager &_channelManager, Notebook *parent
this->ui.hbox.setSpacing(1); this->ui.hbox.setSpacing(1);
this->ui.hbox.setMargin(0); this->ui.hbox.setMargin(0);
this->loadSplits();
this->refreshTitle(); this->refreshTitle();
} }
@ -108,6 +115,7 @@ void SplitContainer::addToLayout(Split *widget, std::pair<int, int> position)
vbox->addWidget(widget); vbox->addWidget(widget);
this->ui.hbox.addLayout(vbox, 1); this->ui.hbox.addLayout(vbox, 1);
this->refreshCurrentFocusCoordinates(); this->refreshCurrentFocusCoordinates();
return; return;
} }
@ -140,9 +148,12 @@ NotebookTab *SplitContainer::getTab() const
return this->tab; return this->tab;
} }
void SplitContainer::addChat(bool openChannelNameDialog) void SplitContainer::addChat(bool openChannelNameDialog, std::string chatUUID)
{ {
Split *w = this->createChatWidget(); if (chatUUID.empty()) {
chatUUID = CreateUUID().toStdString();
}
Split *w = this->createChatWidget(chatUUID);
if (openChannelNameDialog) { if (openChannelNameDialog) {
bool ret = w->showChangeChannelPopup("Open channel", true); bool ret = w->showChangeChannelPopup("Open channel", true);
@ -418,9 +429,9 @@ std::pair<int, int> SplitContainer::getChatPosition(const Split *chatWidget)
return getWidgetPositionInLayout(layout, chatWidget); return getWidgetPositionInLayout(layout, chatWidget);
} }
Split *SplitContainer::createChatWidget() Split *SplitContainer::createChatWidget(const std::string &uuid)
{ {
return new Split(this->channelManager, this); return new Split(this->channelManager, this, uuid);
} }
void SplitContainer::refreshTitle() void SplitContainer::refreshTitle()
@ -454,81 +465,82 @@ void SplitContainer::refreshTitle()
this->tab->setTitle(newTitle); this->tab->setTitle(newTitle);
} }
void SplitContainer::load(const boost::property_tree::ptree &tree) void SplitContainer::loadSplits()
{ {
try { const auto hboxes = this->chats.getValue();
int column = 0; int column = 0;
for (const auto &v : tree.get_child("columns.")) { for (const std::vector<std::string> &hbox : hboxes) {
int row = 0; int row = 0;
for (const auto &innerV : v.second.get_child("")) { for (const std::string &chatUUID : hbox) {
auto widget = this->createChatWidget(); Split *split = this->createChatWidget(chatUUID);
widget->load(innerV.second);
addToLayout(widget, std::pair<int, int>(column, row)); this->addToLayout(split, std::pair<int, int>(column, row));
++row; ++row;
} }
++column; ++column;
} }
} catch (boost::property_tree::ptree_error &) {
// can't read tabs
}
} }
static void saveFromLayout(QLayout *layout, boost::property_tree::ptree &tree) template <typename Container>
static void saveFromLayout(QLayout *layout, Container &container)
{ {
for (int i = 0; i < layout->count(); ++i) { for (int i = 0; i < layout->count(); ++i) {
auto item = layout->itemAt(i); auto item = layout->itemAt(i);
auto innerLayout = item->layout(); auto innerLayout = item->layout();
if (innerLayout != nullptr) { if (innerLayout != nullptr) {
boost::property_tree::ptree innerLayoutTree; std::vector<std::string> vbox;
saveFromLayout(innerLayout, innerLayoutTree);
if (innerLayoutTree.size() > 0) {
tree.push_back(std::make_pair("", innerLayoutTree));
}
for (int j = 0; j < innerLayout->count(); ++j) {
auto innerItem = innerLayout->itemAt(j);
auto innerWidget = innerItem->widget();
if (innerWidget == nullptr) {
assert(false);
continue; continue;
} }
Split *innerSplit = qobject_cast<Split *>(innerWidget);
auto widget = item->widget(); vbox.push_back(innerSplit->getUUID());
if (widget == nullptr) {
// This layoutitem does not manage a widget for some reason
continue;
} }
Split *chatWidget = qobject_cast<Split *>(widget); container.push_back(vbox);
if (chatWidget != nullptr) {
boost::property_tree::ptree chat = chatWidget->save();
tree.push_back(std::make_pair("", chat));
continue; continue;
} }
} }
} }
boost::property_tree::ptree SplitContainer::save() void SplitContainer::save()
{ {
boost::property_tree::ptree tree;
auto layout = this->ui.hbox.layout(); auto layout = this->ui.hbox.layout();
saveFromLayout(layout, tree); std::vector<std::vector<std::string>> _chats;
/* for (int i = 0; i < layout->count(); ++i) {
for (const auto &chat : this->chatWidgets) { auto item = layout->itemAt(i);
boost::property_tree::ptree child = chat->save();
// Set child position auto innerLayout = item->layout();
child.put("position", "5,3"); if (innerLayout != nullptr) {
std::vector<std::string> vbox;
tree.push_back(std::make_pair("", child)); for (int j = 0; j < innerLayout->count(); ++j) {
auto innerItem = innerLayout->itemAt(j);
auto innerWidget = innerItem->widget();
if (innerWidget == nullptr) {
assert(false);
continue;
}
Split *innerSplit = qobject_cast<Split *>(innerWidget);
vbox.push_back(innerSplit->getUUID());
} }
*/
return tree; _chats.push_back(vbox);
continue;
}
}
this->chats = _chats;
} }
} // namespace widgets } // namespace widgets

View file

@ -11,8 +11,6 @@
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QVector> #include <QVector>
#include <QWidget> #include <QWidget>
#include <boost/property_tree/ptree.hpp>
#include <boost/signals2.hpp>
namespace chatterino { namespace chatterino {
@ -24,8 +22,12 @@ class SplitContainer : public BaseWidget
{ {
Q_OBJECT Q_OBJECT
const std::string settingPrefix;
std::string settingRoot;
public: public:
SplitContainer(ChannelManager &_channelManager, Notebook *parent, NotebookTab *_tab); SplitContainer(ChannelManager &_channelManager, Notebook *parent, NotebookTab *_tab,
const std::string &_settingPrefix);
ChannelManager &channelManager; ChannelManager &channelManager;
@ -35,7 +37,7 @@ public:
const std::vector<Split *> &getChatWidgets() const; const std::vector<Split *> &getChatWidgets() const;
NotebookTab *getTab() const; NotebookTab *getTab() const;
void addChat(bool openChannelNameDialog = false); void addChat(bool openChannelNameDialog = false, std::string chatUUID = std::string());
static bool isDraggingSplit; static bool isDraggingSplit;
static Split *draggingSplit; static Split *draggingSplit;
@ -88,19 +90,22 @@ private:
std::vector<Split *> chatWidgets; std::vector<Split *> chatWidgets;
std::vector<DropRegion> dropRegions; std::vector<DropRegion> dropRegions;
pajlada::Settings::Setting<std::vector<std::vector<std::string>>> chats;
NotebookPageDropPreview dropPreview; NotebookPageDropPreview dropPreview;
void setPreviewRect(QPoint mousePos); void setPreviewRect(QPoint mousePos);
std::pair<int, int> getChatPosition(const Split *chatWidget); std::pair<int, int> getChatPosition(const Split *chatWidget);
Split *createChatWidget(); Split *createChatWidget(const std::string &uuid);
public: public:
void refreshTitle(); void refreshTitle();
void load(const boost::property_tree::ptree &tree); void loadSplits();
boost::property_tree::ptree save();
void save();
}; };
} // namespace widgets } // namespace widgets

View file

@ -14,14 +14,14 @@
namespace chatterino { namespace chatterino {
namespace widgets { namespace widgets {
Window::Window(const QString &_windowName, ChannelManager &_channelManager, Window::Window(const QString &windowName, ChannelManager &_channelManager,
ColorScheme &_colorScheme, bool _isMainWindow) ColorScheme &_colorScheme, bool _isMainWindow)
: BaseWidget(_colorScheme, nullptr) : BaseWidget(_colorScheme, nullptr)
, windowName(_windowName) , settingRoot(fS("/windows/{}", windowName))
, windowGeometry(this->windowName.toStdString()) , windowGeometry(this->settingRoot)
, channelManager(_channelManager) , channelManager(_channelManager)
, colorScheme(_colorScheme) , colorScheme(_colorScheme)
, notebook(this->channelManager, this, _isMainWindow) , notebook(this->channelManager, this, _isMainWindow, this->settingRoot)
, dpi(this->getDpiMultiplier()) , dpi(this->getDpiMultiplier())
{ {
this->initAsWindow(); this->initAsWindow();
@ -85,36 +85,6 @@ void Window::repaintVisibleChatWidgets(Channel *channel)
} }
} }
void Window::load(const boost::property_tree::ptree &tree)
{
this->notebook.load(tree);
loaded = true;
}
boost::property_tree::ptree Window::save()
{
boost::property_tree::ptree child;
child.put("type", "main");
this->notebook.save(child);
return child;
}
void Window::loadDefaults()
{
this->notebook.loadDefaults();
loaded = true;
}
bool Window::isLoaded() const
{
return loaded;
}
Notebook &Window::getNotebook() Notebook &Window::getNotebook()
{ {
return this->notebook; return this->notebook;
@ -158,5 +128,10 @@ void Window::loadGeometry()
} }
} }
void Window::save()
{
this->notebook.save();
}
} // namespace widgets } // namespace widgets
} // namespace chatterino } // namespace chatterino

View file

@ -9,7 +9,6 @@
//#include <platform/borderless/qwinwidget.h> //#include <platform/borderless/qwinwidget.h>
//#endif //#endif
#include <boost/property_tree/ptree.hpp>
#include <boost/signals2.hpp> #include <boost/signals2.hpp>
#include <pajlada/settings/setting.hpp> #include <pajlada/settings/setting.hpp>
@ -22,11 +21,11 @@ class CompletionManager;
namespace widgets { namespace widgets {
struct WindowGeometry { struct WindowGeometry {
WindowGeometry(const std::string &key) WindowGeometry(const std::string &settingPrefix)
: x(fS("/windows/{}/geometry/x", key)) : x(fS("{}/geometry/x", settingPrefix))
, y(fS("/windows/{}/geometry/y", key)) , y(fS("{}/geometry/y", settingPrefix))
, width(fS("/windows/{}/geometry/width", key)) , width(fS("{}/geometry/width", settingPrefix))
, height(fS("/windows/{}/geometry/height", key)) , height(fS("{}/geometry/height", settingPrefix))
{ {
} }
@ -40,22 +39,16 @@ class Window : public BaseWidget
{ {
Q_OBJECT Q_OBJECT
QString windowName; std::string settingRoot;
WindowGeometry windowGeometry; WindowGeometry windowGeometry;
public: public:
explicit Window(const QString &_windowName, ChannelManager &_channelManager, explicit Window(const QString &windowName, ChannelManager &_channelManager,
ColorScheme &_colorScheme, bool isMainWindow); ColorScheme &_colorScheme, bool isMainWindow);
void repaintVisibleChatWidgets(Channel *channel = nullptr); void repaintVisibleChatWidgets(Channel *channel = nullptr);
void load(const boost::property_tree::ptree &tree);
boost::property_tree::ptree save();
void loadDefaults();
bool isLoaded() const;
Notebook &getNotebook(); Notebook &getNotebook();
void refreshWindowTitle(const QString &username); void refreshWindowTitle(const QString &username);
@ -76,10 +69,12 @@ private:
ColorScheme &colorScheme; ColorScheme &colorScheme;
Notebook notebook; Notebook notebook;
bool loaded = false;
TitleBar titleBar; TitleBar titleBar;
friend class Notebook; friend class Notebook;
public:
void save();
}; };
} // namespace widgets } // namespace widgets

View file

@ -7,7 +7,6 @@
#include <QDebug> #include <QDebug>
#include <QStandardPaths> #include <QStandardPaths>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/property_tree/json_parser.hpp>
namespace chatterino { namespace chatterino {
WindowManager *WindowManager::instance = nullptr; WindowManager *WindowManager::instance = nullptr;
@ -70,8 +69,6 @@ widgets::Window &WindowManager::createWindow()
{ {
auto *window = new widgets::Window("external", this->channelManager, this->colorScheme, false); auto *window = new widgets::Window("external", this->channelManager, this->colorScheme, false);
window->loadDefaults();
this->windows.push_back(window); this->windows.push_back(window);
return *window; return *window;
@ -92,65 +89,15 @@ widgets::Window *WindowManager::windowAt(int index)
return this->windows.at(index); return this->windows.at(index);
} }
void WindowManager::load()
{
const auto &settingsPath = getSettingsPath();
boost::property_tree::ptree tree;
try {
boost::property_tree::read_json(settingsPath, tree);
} catch (const boost::property_tree::json_parser_error &ex) {
qDebug() << "Error using property_tree::readJson: " << QString::fromStdString(ex.message());
getMainWindow().loadDefaults();
return;
}
// Read a list of windows
try {
BOOST_FOREACH (const boost::property_tree::ptree::value_type &v,
tree.get_child("windows.")) {
qDebug() << QString::fromStdString(v.first.data());
const auto &type = v.second.get<std::string>("type", "unknown");
if (type == "main") {
getMainWindow().load(v.second);
} else {
qDebug() << "Unhandled window type: " << type.c_str();
}
}
} catch (boost::property_tree::ptree_error &) {
// can't read windows
}
// if the main window was not loaded properly, load defaults
if (!getMainWindow().isLoaded()) {
getMainWindow().loadDefaults();
}
// If there are no windows, create a default main window
}
void WindowManager::save() void WindowManager::save()
{ {
auto &settingsPath = getSettingsPath(); assert(this->mainWindow);
boost::property_tree::ptree tree;
// Create windows array this->mainWindow->save();
boost::property_tree::ptree windows;
{ for (widgets::Window *window : this->windows) {
// save main window window->save();
auto child = getMainWindow().save();
windows.push_back(std::make_pair("", child));
} }
// TODO: iterate through rest of windows and add them to the "windows" ptree
tree.add_child("windows", windows);
boost::property_tree::write_json(settingsPath, tree);
} }
} // namespace chatterino } // namespace chatterino

View file

@ -31,7 +31,6 @@ public:
int windowCount(); int windowCount();
widgets::Window *windowAt(int index); widgets::Window *windowAt(int index);
void load();
void save(); void save();
boost::signals2::signal<void()> repaintGifs; boost::signals2::signal<void()> repaintGifs;