Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ set(client_UI_SRCS
settingsdialog.ui
tlserrordialog.ui
logbrowser.ui
accountview.ui
accountsgui/accountview.ui
)

set(client_SRCS
aboutdialog.cpp
accountmanager.cpp
accountview.cpp

accountmodalwidget.cpp
accountmodalwidget.ui
Expand Down Expand Up @@ -118,6 +117,8 @@ add_subdirectory(newaccountwizard)
add_subdirectory(socketapi)
add_subdirectory(spaces)
add_subdirectory(FoldersGui)
add_subdirectory(mainwindow)
add_subdirectory(accountsgui)

target_include_directories(owncloudGui PUBLIC
${CMAKE_SOURCE_DIR}/src/3rdparty/QProgressIndicator
Expand Down
5 changes: 5 additions & 0 deletions src/gui/accountmodalwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ namespace Ui {
class AccountModalWidget;
}

// this class is basically a "wrapper" that hosts a widget/panel that we want to run in a modal concept.
// basically it adds a title to the given widget, and provides buttons (normally ok/cancel) that control the lifetime of
// the "modality"
// the class is used in the AccountView with account related stuff
// it's basically a reproduction of a modal dialog but it's embedded in the account view of the main window.
class AccountModalWidget : public QWidget
{
Q_OBJECT
Expand Down
7 changes: 7 additions & 0 deletions src/gui/accountsgui/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
target_sources(owncloudGui PRIVATE
accountsguicontroller.cpp
accountsguicontroller.h
accountview.cpp
accountview.h
)

10 changes: 10 additions & 0 deletions src/gui/accountsgui/accountsguicontroller.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "accountsguicontroller.h"

namespace OCC {

AccountsGuiController::AccountsGuiController(QObject *parent)
: QObject(parent)
{
}

}
13 changes: 13 additions & 0 deletions src/gui/accountsgui/accountsguicontroller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include <QObject>

namespace OCC {
class AccountsGuiController : public QObject
{
Q_OBJECT

public:
AccountsGuiController(QObject *parent);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,10 @@ void AccountView::onRequestAccountModalWidget(OCC::AccountModalWidget *widget)
addModalAccountWidget(widget);
}

// notes to self: the "modal" stuff is in this direction: the accountView sometimes wants to show something in a manner
// that users should finish the activity. The accountview shows the gui the user should interact with, but it has to ask the
// main window layer to block other user activity in the meantime. I think conceptually it's ok but the impl needs to be
// simplified, especially to get rid of the legacy vs non legacy impls
void AccountView::addModalAccountWidget(AccountModalWidget *widget)
{
if (!_accountState || !_accountState->account()) {
Expand Down
File renamed without changes.
File renamed without changes.
12 changes: 12 additions & 0 deletions src/gui/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "configfile.h"
#include "folder.h"
#include "folderman.h"
#include "mainwindow/mainwindow.h"
#include "mainwindow/mainwindowcontroller.h"
#include "settingsdialog.h"
#include "socketapi/socketapi.h"
#include "theme.h"
Expand Down Expand Up @@ -90,6 +92,11 @@ Application::Application(Platform *platform, const QString &displayLanguage, boo
// setup that follows, like folder setup
_gui = new ownCloudGui(this);

#ifdef USE_NEW_MAIN_WINDOW
_mainWin = new MainWindow();
_mainController = new MainWindowController(_mainWin, this);
#endif

connect(AccountManager::instance(), &AccountManager::accountAdded, this, &Application::slotAccountStateAdded);
connect(AccountManager::instance(), &AccountManager::lastAccountRemoved, this, &Application::lastAccountStateRemoved);
for (const auto &ai : AccountManager::instance()->accounts()) {
Expand Down Expand Up @@ -121,6 +128,11 @@ Application::~Application()
// Make sure all folders are gone, otherwise removing the
// accounts will remove the associated folders from the settings.
FolderMan::instance()->unloadAndDeleteAllFolders();

if (_mainWin) {
_mainWin->disconnect();
delete _mainWin;
}
}

void Application::lastAccountStateRemoved() const
Expand Down
8 changes: 8 additions & 0 deletions src/gui/application.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ Q_DECLARE_LOGGING_CATEGORY(lcApplication)

class Theme;
class Folder;
class MainWindow;
class MainWindowController;

/**
* @brief The Application class
Expand All @@ -52,6 +54,9 @@ class OWNCLOUDGUI_EXPORT Application : public QObject

ownCloudGui *gui() const;

// try to get rid of this before the end. currently needed to raise the main window via owncloudgui
MainWindow *mainWindow() { return _mainWin; }

QString displayLanguage() const;

/**
Expand All @@ -77,6 +82,9 @@ protected Q_SLOTS:

QPointer<ownCloudGui> _gui = {};

MainWindow *_mainWin = nullptr;
MainWindowController *_mainController = nullptr;

const bool _debugMode = false;
QString _displayLanguage;

Expand Down
5 changes: 5 additions & 0 deletions src/gui/creds/credentials.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,11 @@ void Credentials::askFromUser()

// the widget is parented to the AccountModalWidget when it's installed in the main window.
// it will be cleaned up there - this is not a leak
// todo dc-300 : this needs to be handled as a "request" to show the gui. The creds are known to the Account
// the account view (or accountsguicontroller, more likely) should be able to connect auth request related signals
// between the account gui and the creds.
// essential to remember though, is that this auth widget is essentially a credentials editor.
// put a pin in it
RequestAuthenticationWidget *widget = new RequestAuthenticationWidget();
_requestAuth = new RequestAuthenticationController(widget, this);
// we should not connect to the failed signal as we are forcing the user to make the decision using the gui.
Expand Down
2 changes: 1 addition & 1 deletion src/gui/creds/requestauthenticationcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*/
#include "requestauthenticationcontroller.h"

#include "accountview.h"
#include "accountsgui/accountview.h"
#include "application.h"
#include "requestauthenticationwidget.h"

Expand Down
9 changes: 5 additions & 4 deletions src/gui/folderman.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,11 @@ public Q_SLOTS:
void removeFolderFromGui(Folder *f);
void forceFolderSync(Folder *f);

// this was private which then required Application be a friend of FolderMan...
// I am not sure why the Application seems to be the "master" minder of account manager signals
// but I think this will soon change
void slotServerVersionChanged(Account *account);

private Q_SLOTS:

void slotFolderSyncPauseChanged(Folder *, bool paused);
Expand All @@ -344,8 +349,6 @@ private Q_SLOTS:

void slotRemoveFoldersForAccount(AccountState *accountState);

void slotServerVersionChanged(Account *account);

// saves folder using an internally created QSettings instance. This is used for "one off" persistence operations
// that should be synced immediately - eg when the user adds a new folder sync from the gui or as slot to eg persist a property
// change
Expand Down Expand Up @@ -510,8 +513,6 @@ private Q_SLOTS:
// set when they are paused/resumed but aside from that we don't really do anything with it.
QSet<Folder *> _disabledFolders;

friend class OCC::Application;

// the literal is needed to get the tests to build
inline static const QString IgnoreHiddenFilesKey = QStringLiteral("ignoreHiddenFiles");
void scheduleFoldersForAccount(const QUuid &accountId);
Expand Down
3 changes: 3 additions & 0 deletions src/gui/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,9 @@ int main(int argc, char **argv)
return -1;
}

// I think this could/should just be a local instance that just naturally goes out of scope. this will take some time though,
// as it's a singleton :/
// good news is that it's mostly used to handle the main window "modal" impls which will likely change or even go away soon-ish
auto ocApp = Application::createInstance(platform.get(), displayLanguage, options.debugMode);
ocApp->updateAutoRun(firstRun);

Expand Down
7 changes: 7 additions & 0 deletions src/gui/mainwindow/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
target_sources(owncloudGui PRIVATE
mainwindow.cpp
mainwindow.h
mainwindowcontroller.cpp
mainwindowcontroller.h
)

132 changes: 132 additions & 0 deletions src/gui/mainwindow/mainwindow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include "mainwindow.h"

#include <QApplication>
#include <QStackedWidget>
#include <QToolBar>
#include <QToolButton>

#include "configfile.h"
#include "theme.h"

#ifdef Q_OS_MAC
#include "settingsdialog_mac.h"
void setActivationPolicy(ActivationPolicy policy);
#endif

namespace OCC {
MainWindow::MainWindow()
: QMainWindow{nullptr}
{
// required as group for saveGeometry call. the original name is "Settings" so we should factor this in
// and make sure we either accept that previous geometry is lost between upgrade/downgrades OR put the name back to Settings
// which imo is a terrible name but we could save the rename til next major version.
// in reality the stored geometry is just the size afaik but will double check. If we had user editable docking positions,
// subwidgets that can run along side the main window, etc. the stored geometry would be more important for user happiness.
setObjectName(QStringLiteral("MainWindow"));
setWindowTitle(Theme::instance()->appNameGUI());

// People perceive this as a Window, so also make Ctrl+W work
addAction(tr("Hide"), Qt::CTRL | Qt::Key_W, this, &MainWindow::hide);

ConfigFile().restoreGeometry(this);
#ifdef Q_OS_MAC
setActivationPolicy(ActivationPolicy::Accessory);
#endif

buildWindow();
}

void MainWindow::buildWindow()
{
// clang is complaining that call to minimumSizeHint bypasses virtual dispatch, but I'm not seeing any problem.
// the link to docs for that warning = 404 :D
// regardless, the evaluation is misleading as according to c++ standard, calling a virtual function in a ctr is guaranteed to
// call the override for the class being constructed. There is no problem here.
// this is part of the reason we have tidy turned off - it's a bit too touchy.
// question is, why is tidy butting in if we have it turned off? Figure this out later.
setMinimumSize(minimumSizeHint());

_toolbar = new QToolBar(this);
_toolbar->setObjectName("mainWindowToolbar");
_toolbar->setMovable(false);
_toolbar->setAccessibleDescription(tr("Main toolbar for the application"));
_toolbar->setAccessibleName(tr("Main toolbar"));
addToolBar(_toolbar);

QWidget *toolbarStretch = new QWidget(this);
// who knows, maybe someday we use the toolbar vertically
toolbarStretch->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
_toolbar->addWidget(toolbarStretch);

_toolbar->addSeparator();

_moreButton = new QToolButton(this);
_moreButton->setText("⋯");
// _moreButton->setToolButtonStyle(Qt::ToolButtonTextOnly);
_moreButton->setPopupMode(QToolButton::InstantPopup);
_toolbar->addWidget(_moreButton);

_widgetStack = new QStackedWidget(this);
setCentralWidget(_widgetStack);
}

void MainWindow::setMoreMenuActions(const QList<QAction *> &actions)
{
_moreButton->addActions(actions);
}

void MainWindow::showModalWidget(QWidget *w)
{
// ownCloudGui::raise();
if (_widgetStack->indexOf(w) == -1) {
_widgetStack->addWidget(w);
_widgetStack->setCurrentWidget(w);
}
}

QSize MainWindow::minimumSizeHint() const
{
const QSize min{800, 700}; // When changing this, please check macOS: widgets there have larger insets, so they take up more space.
const auto screen = windowHandle() ? windowHandle()->screen() : QApplication::screenAt(QCursor::pos());
if (screen) {
const auto availableSize = screen->availableSize();
if (availableSize.isValid()) {
// Assume we can use at least 90% of the screen, if the screen is smaller than 800x700 pixels.
//
// Note: this means that the wizards have even less space: with the style we use, the
// wizard tries to fit inside the window. So, if this is a common case that users have
// such small screens, and the contents of the wizard screen are squashed together (or
// not shown due to lack of space), we should consider putting that content in a
// scroll-view.
return min.boundedTo(availableSize * 0.9);
}
}
return min;
}

void MainWindow::setVisible(bool visible)
{
if (!visible) {
ConfigFile cfg;
cfg.saveGeometry(this);
}

#ifdef Q_OS_MAC
if (visible) {
setActivationPolicy(ActivationPolicy::Regular);
} else {
setActivationPolicy(ActivationPolicy::Accessory);
}
#endif

QMainWindow::setVisible(visible);
}
// envisioning:
// the actions for changing the current panel in the main window have a panel id as data
// so the main window controller just needs to find this id in the panel collection and show it.
// building the panel, its controller, and "installing" it on the main window with it's id should be up to
// an application (window) builder so the main window isn't responsible for knowing how many or which panels live in it.
// this is very powerful when it comes to adding or removing guis depending on....stuff.


}
40 changes: 40 additions & 0 deletions src/gui/mainwindow/mainwindow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once

#include <QMainWindow>

class QToolBar;
class QToolButton;
class QStackedWidget;

namespace OCC {
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow();

QSize minimumSizeHint() const override;

void setVisible(bool visible) override;

void setMoreMenuActions(const QList<QAction *> &actions);

void showModalWidget(QWidget *w);

private:
void buildWindow();

QToolBar *_toolbar = nullptr;
QStackedWidget *_widgetStack = nullptr;

QToolButton *_moreButton = nullptr;

// hash of panel id's to panel widgets. the id is encapsulated in the main window's toolbar and menu actions
// when the window "hears" that an action was triggered, it should just show the widget associated with the
// action's id.
// this will need refinement for the elements that currently run in the "modal" impls - maybe those go away
// completely, no idea yet. but this is a good start so that the main window isn't controlling any of the activities related
// to the panels. they need to control themselves!
QHash<int, QWidget *> _panelLookup;
};
}
Loading
Loading