logic: file associations for Mac and opening project files via Mac OS

* hide start screen when opening with project file
* added project icon file to bundle and file type association to plist
* listen for file open events from double click or drag and drop
* fixed crashes in window handling
This commit is contained in:
Eberhard Graether
2016-02-02 13:20:05 +01:00
parent 29a70b8f70
commit 3cbafa6456
18 changed files with 183 additions and 40 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

+15
View File
@@ -40,5 +40,20 @@
<string>icon</string>
<key>LSMinimumSystemVersion</key>
<string>10.9</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleTypeName</key>
<string>Coati Project</string>
<key>CFBundleTypeExtensions</key>
<array>
<string>coatiproject</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>project</string>
</dict>
</array>
</dict>
</plist>
+24 -4
View File
@@ -102,9 +102,9 @@ do
echo "lib" $LIB_PATH $LIB_NAME
done
echo -e $INFO "Fixing lib dependencies"
install_name_tool -change libboost_system.dylib @executable_path/../lib/libboost_system.dylib $DYNLIB_DIR/libboost_filesystem.dylib
otool -L $DYNLIB_DIR/libboost_filesystem.dylib
# echo -e $INFO "Fixing lib dependencies"
# install_name_tool -change libboost_system.dylib @executable_path/../lib/libboost_system.dylib $DYNLIB_DIR/libboost_filesystem.dylib
# otool -L $DYNLIB_DIR/libboost_filesystem.dylib
echo -e $INFO "Copying Plugins"
@@ -160,7 +160,7 @@ echo -e $INFO "App dependencies"
otool -L $APP_PATH
echo -e $INFO "Create icon"
ICON=../data/gui/installer/logo_1024_1024.png
ICON=../data/gui/icon/logo_1024_1024.png
ICON_SET=$RES_DIR/icon.iconset
mkdir -p $ICON_SET
@@ -177,6 +177,26 @@ convert $ICON -resize 1024x1024 $ICON_SET/icon_512x512@2x.png
iconutil -c icns -o $RES_DIR/icon.icns $ICON_SET
echo -e $INFO "Create project icon"
ICON=../data/gui/icon/project_256_256.png
ICON_SET=$RES_DIR/project.iconset
mkdir -p $ICON_SET
convert $ICON -resize 16x16 $ICON_SET/icon_16x16.png
convert $ICON -resize 32x32 $ICON_SET/icon_16x16@2x.png
convert $ICON -resize 32x32 $ICON_SET/icon_32x32.png
convert $ICON -resize 64x64 $ICON_SET/icon_32x32@2x.png
convert $ICON -resize 64x64 $ICON_SET/icon_64x64.png
convert $ICON -resize 128x128 $ICON_SET/icon_64x64@2x.png
convert $ICON -resize 128x128 $ICON_SET/icon_128x128.png
convert $ICON -resize 256x256 $ICON_SET/icon_128x128@2x.png
convert $ICON -resize 256x256 $ICON_SET/icon_256x256.png
convert $ICON -resize 512x512 $ICON_SET/icon_256x256@2x.png
convert $ICON -resize 512x512 $ICON_SET/icon_512x512.png
convert $ICON -resize 1024x1024 $ICON_SET/icon_512x512@2x.png
iconutil -c icns -o $RES_DIR/project.icns $ICON_SET
echo -e $INFO "Obfuscate binary"
# upx -1 $APP_PATH
upx --best $APP_PATH
+30 -3
View File
@@ -2,6 +2,7 @@
#define LICENSE_CHECKER_H
#include "utility/messaging/MessageListener.h"
#include "utility/messaging/type/MessageEnteredLicense.h"
#include "utility/messaging/type/MessageLoadProject.h"
#include "utility/messaging/type/MessageStatus.h"
@@ -12,25 +13,49 @@
#include "utility/AppPath.h"
class LicenseChecker
: public MessageListener<MessageLoadProject>
: public MessageListener<MessageEnteredLicense>
, public MessageListener<MessageLoadProject>
{
public:
LicenseChecker()
: m_forcedLicenseEntering(false)
{
}
inline void setApp(Application* app)
{
m_app = app;
if (!checkLicenseString())
if (!m_forcedLicenseEntering && !checkLicenseString())
{
m_app->showLicenseScreen();
m_forcedLicenseEntering = true;
}
}
private:
void handleMessage(MessageEnteredLicense* message)
{
m_forcedLicenseEntering = false;
if (m_resendMessage)
{
m_resendMessage->dispatch();
m_resendMessage.reset();
}
}
void handleMessage(MessageLoadProject* message)
{
if (!checkLicenseString())
{
m_resendMessage = std::make_shared<MessageLoadProject>(*message);
message->cancel();
m_app->showLicenseScreen();
if (!m_forcedLicenseEntering)
{
m_app->showLicenseScreen();
m_forcedLicenseEntering = true;
}
}
}
@@ -77,6 +102,8 @@ private:
}
Application* m_app;
std::shared_ptr<MessageBase> m_resendMessage;
bool m_forcedLicenseEntering;
};
#endif // LICENSE_CHECKER_H
+10 -13
View File
@@ -1,25 +1,22 @@
#include <memory>
#include <QApplication>
#include "utility/AppPath.h"
#include "utility/logging/ConsoleLogger.h"
#include "utility/logging/FileLogger.h"
#include "utility/logging/LogManager.h"
#include "utility/ResourcePaths.h"
#include "utility/Version.h"
#include "Application.h"
#include "includes.h" // defines 'void setup(int argc, char *argv[])'
#include "LicenseChecker.h"
#include "qt/commandline/QtCommandLineParser.h"
#include "qt/window/QtMainWindow.h"
#include "qt/window/QtSplashScreen.h"
#include "qt/network/QtNetworkFactory.h"
#include "qt/QtApplication.h"
#include "qt/utility/utilityQt.h"
#include "qt/view/QtViewFactory.h"
#include "qt/window/QtMainWindow.h"
#include "qt/window/QtSplashScreen.h"
#include "version.h"
#include "utility/AppPath.h"
#include "utility/ResourcePaths.h"
void init()
{
@@ -40,14 +37,10 @@ int main(int argc, char *argv[])
Version version = Version::fromString(GIT_VERSION_NUMBER);
setup(argc, argv);
QApplication qtApp(argc, argv);
QtApplication qtApp(argc, argv);
QApplication::setApplicationName("Coati");
QApplication::setApplicationVersion(version.toDisplayString().c_str());
QtCommandLineParser commandLineParser;
commandLineParser.setup();
commandLineParser.process(qtApp);
qtApp.setAttribute(Qt::AA_UseHighDpiPixmaps);
QPixmap whitePixmap(500, 500);
@@ -60,6 +53,10 @@ int main(int argc, char *argv[])
init();
QtCommandLineParser commandLineParser;
commandLineParser.setup();
commandLineParser.process(qtApp);
QtViewFactory viewFactory;
QtNetworkFactory networkFactory;
+9 -3
View File
@@ -46,6 +46,8 @@ std::shared_ptr<Application> Application::create(
ptr->m_ideCommunicationController = networkFactory->createIDECommunicationController(ptr->m_storageCache.get());
ptr->startMessagingAndScheduling();
return ptr;
}
@@ -59,9 +61,6 @@ void Application::loadSettings()
Application::Application()
{
TaskScheduler::getInstance()->startSchedulerLoopThreaded();
MessageQueue::getInstance()->setSendMessagesAsTasks(true);
MessageQueue::getInstance()->startMessageLoopThreaded();
}
Application::~Application()
@@ -161,6 +160,13 @@ void Application::handleMessage(MessageSaveProject* message)
saveProject(message->projectSettingsFilePath);
}
void Application::startMessagingAndScheduling()
{
TaskScheduler::getInstance()->startSchedulerLoopThreaded();
MessageQueue::getInstance()->setSendMessagesAsTasks(true);
MessageQueue::getInstance()->startMessageLoopThreaded();
}
void Application::updateRecentProjects(const FilePath& projectSettingsFilePath)
{
ApplicationSettings* appSettings = ApplicationSettings::getInstance().get();
+2
View File
@@ -48,6 +48,8 @@ private:
virtual void handleMessage(MessageRefresh* message);
virtual void handleMessage(MessageSaveProject* message);
void startMessagingAndScheduling();
void updateRecentProjects(const FilePath& projectSettingsFilePath);
std::shared_ptr<Project> m_project;
+1
View File
@@ -223,6 +223,7 @@ add_files(
utility/messaging/type/MessageChangeFileView.h
utility/messaging/type/MessageClearErrorCount.h
utility/messaging/type/MessageDeactivateEdge.h
utility/messaging/type/MessageEnteredLicense.h
utility/messaging/type/MessageFind.h
utility/messaging/type/MessageFinishedParsing.h
utility/messaging/type/MessageFlushUpdates.h
@@ -0,0 +1,21 @@
#ifndef MESSAGE_ENTERED_LICENSE_H
#define MESSAGE_ENTERED_LICENSE_H
#include "utility/messaging/Message.h"
class MessageEnteredLicense
: public Message<MessageEnteredLicense>
{
public:
MessageEnteredLicense()
{
setSendAsTask(false);
}
static const std::string getStaticType()
{
return "MessageEnteredLicense";
}
};
#endif // MESSAGE_ENTERED_LICENSE_H
+3
View File
@@ -119,4 +119,7 @@ add_files(
qt/window/QtSplashScreen.h
qt/window/QtStartScreen.cpp
qt/window/QtStartScreen.h
qt/QtApplication.cpp
qt/QtApplication.h
)
+30
View File
@@ -0,0 +1,30 @@
#include "qt/QtApplication.h"
#include <QFileOpenEvent>
#include "utility/file/FilePath.h"
#include "utility/messaging/type/MessageLoadProject.h"
QtApplication::QtApplication(int& argc, char** argv)
: QApplication(argc, argv)
{
}
// responds to FileOpenEvent specific for Mac
bool QtApplication::event(QEvent *event)
{
if (event->type() == QEvent::FileOpen)
{
QFileOpenEvent* fileEvent = dynamic_cast<QFileOpenEvent*>(event);
FilePath path(fileEvent->file().toStdString());
if (path.exists() && path.extension() == ".coatiproject")
{
MessageLoadProject(path.str(), false).dispatch();
return true;
}
}
return QApplication::event(event);
}
+15
View File
@@ -0,0 +1,15 @@
#ifndef QT_APPLICATION_H
#define QT_APPLICATION_H
#include <QApplication>
class QtApplication
: public QApplication
{
public:
QtApplication(int& argc, char** argv);
bool event(QEvent *event);
};
#endif // QT_APPLICATION_H
+8 -2
View File
@@ -5,7 +5,8 @@
#include "qt/window/QtMainWindow.h"
QtMainView::QtMainView()
: m_setTitleFunctor(std::bind(&QtMainView::doSetTitle, this, std::placeholders::_1))
: m_hideStartScreenFunctor(std::bind(&QtMainView::doHideStartScreen, this))
, m_setTitleFunctor(std::bind(&QtMainView::doSetTitle, this, std::placeholders::_1))
, m_activateWindowFunctor(std::bind(&QtMainView::doActivateWindow, this))
, m_updateRecentProjectMenuFunctor(std::bind(&QtMainView::doUpdateRecentProjectMenu, this))
, m_showLicenseScreenFunctor(std::bind(&QtMainView::doShowLicenseScreen, this))
@@ -69,7 +70,7 @@ void QtMainView::setStatusBar(QStatusBar* statusbar)
void QtMainView::hideStartScreen()
{
m_window->clearWindows();
m_hideStartScreenFunctor();
}
void QtMainView::setTitle(const std::string& title)
@@ -97,6 +98,11 @@ void QtMainView::doUpdateRecentProjectMenu()
m_window->updateRecentProjectMenu();
}
void QtMainView::doHideStartScreen()
{
m_window->clearWindows();
}
void QtMainView::doSetTitle(const std::string& title)
{
m_window->setWindowTitle(QString::fromStdString(title));
+2
View File
@@ -40,6 +40,7 @@ public:
virtual void showLicenseScreen();
private:
void doHideStartScreen();
void doSetTitle(const std::string& title);
void doActivateWindow();
void doUpdateRecentProjectMenu();
@@ -48,6 +49,7 @@ private:
std::shared_ptr<QtMainWindow> m_window;
std::vector<View*> m_views;
QtThreadedFunctor<> m_hideStartScreenFunctor;
QtThreadedFunctor<const std::string&> m_setTitleFunctor;
QtThreadedFunctor<> m_activateWindowFunctor;
QtThreadedFunctor<> m_updateRecentProjectMenuFunctor;
+4 -1
View File
@@ -12,8 +12,9 @@
#include "PublicKey.h"
#include "qt/utility/utilityQt.h"
#include "settings/ApplicationSettings.h"
#include "utility/file/FilePath.h"
#include "utility/AppPath.h"
#include "utility/file/FilePath.h"
#include "utility/messaging/type/MessageEnteredLicense.h"
#include "utility/ResourcePaths.h"
QtLicense::QtLicense(QWidget *parent)
@@ -152,6 +153,8 @@ void QtLicense::handleUpdateButtonPress()
FilePath p(appLocation);
appSettings->setLicenseCheck(license.hashLocation(p.absolute().str()));
appSettings->save();
MessageEnteredLicense().dispatch();
}
else
{
+3 -5
View File
@@ -62,8 +62,6 @@ bool MouseReleaseFilter::eventFilter(QObject* obj, QEvent* event)
{
QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>(event);
if (mouseEvent->button() == m_backButton)
{
MessageUndo().dispatch();
@@ -82,7 +80,6 @@ bool MouseReleaseFilter::eventFilter(QObject* obj, QEvent* event)
MouseWheelFilter::MouseWheelFilter(QObject* parent)
: QObject(parent)
{
}
bool MouseWheelFilter::eventFilter(QObject* obj, QEvent* event)
@@ -106,6 +103,7 @@ bool MouseWheelFilter::eventFilter(QObject* obj, QEvent* event)
return QObject::eventFilter(obj, event);
}
QtMainWindow::QtMainWindow()
: m_showDockWidgetTitleBars(true)
{
@@ -300,9 +298,9 @@ void QtMainWindow::popWindow()
void QtMainWindow::clearWindows()
{
if (m_windowStack.size())
for (QWidget* window : m_windowStack)
{
m_windowStack.back()->hide();
window->hide();
}
m_windowStack.clear();
+1
View File
@@ -63,6 +63,7 @@ protected:
bool eventFilter(QObject* obj, QEvent* event);
};
class QtMainWindow
: public QMainWindow
{
+5 -9
View File
@@ -1,24 +1,20 @@
#include <memory>
#include <QApplication>
#include "utility/AppPath.h"
#include "utility/logging/ConsoleLogger.h"
#include "utility/logging/FileLogger.h"
#include "utility/logging/LogManager.h"
#include "utility/AppPath.h"
#include "utility/ResourcePaths.h"
#include "utility/Version.h"
#include "Application.h"
#include "includes.h" // defines 'void setup(int argc, char *argv[])'
#include "qt/window/QtMainWindow.h"
#include "qt/window/QtSplashScreen.h"
#include "qt/network/QtNetworkFactory.h"
#include "qt/QtApplication.h"
#include "qt/utility/utilityQt.h"
#include "qt/view/QtViewFactory.h"
#include "qt/window/QtMainWindow.h"
#include "qt/window/QtSplashScreen.h"
#include "version.h"
#include "component/controller/helper/NetworkProtocolHelper.h" // remove when done
void init()
{
@@ -39,7 +35,7 @@ int main(int argc, char *argv[])
Version version = Version::fromString(GIT_VERSION_NUMBER);
setup(argc, argv);
QApplication qtApp(argc, argv);
QtApplication qtApp(argc, argv);
qtApp.setAttribute(Qt::AA_UseHighDpiPixmaps);