Skip to content
Snippets Groups Projects
Commit fc99eb02 authored by marco's avatar marco
Browse files

added install command-line tool dialog

a dialog pop-up the first time a user starts DNG on the Mac and
asks if symlinks for the command-line tools should be created.

git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@2595 5a81b35b-ba03-0410-adc8-b2c5c5119f08
parent 1176da72
Branches
Tags
No related merge requests found
...@@ -84,8 +84,14 @@ set(OST_GUI_PYMOD_MODULES ...@@ -84,8 +84,14 @@ set(OST_GUI_PYMOD_MODULES
init_splash.py init_splash.py
) )
set(OST_GUI_PYMOD_DNG_MODULES
__init__.py
termuse.py
)
pymod(NAME gui CPP ${OST_GUI_PYMOD_SOURCES} pymod(NAME gui CPP ${OST_GUI_PYMOD_SOURCES}
PY ${OST_GUI_SCENE_PYMOD_MODULES} IN_DIR scene PY ${OST_GUI_SCENE_PYMOD_MODULES} IN_DIR scene
${OST_GUI_PYMOD_DNG_MODULES} IN_DIR dng
${OST_GUI_PYMOD_MODULES}) ${OST_GUI_PYMOD_MODULES})
set(PRESET_FILES set(PRESET_FILES
......
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from ost.gui import AdminRights
import ost
import os
#from ost.gui import AdminRights
usage='''The DNG application bundle contains two shell commands ('ost' and 'dng') that lets you use the OpenStructure command-line interpreter and dng from the terminal. If you want to use these commands, it is recommended that a symbolic link is created.
'''
class TerminalUsageDialog(QDialog):
def __init__(self, parent=None):
QDialog.__init__(self, parent)
self.setWindowTitle('Enhanced Terminal Usage')
self.setFixedSize(QSize(480, 300))
l=QVBoxLayout(self)
title=QLabel('Enhanced Terminal Usage')
font=title.font()
font.setPointSize(20)
title.setFont(font)
l.addWidget(title)
text=QLabel(usage)
l.addWidget(text)
l2=QHBoxLayout()
l2.addWidget(QLabel('If you proceed, the link will be created in: '))
self.path_combo=QComboBox()
self.path_combo.setFixedWidth(150)
for path in os.getenv('PATH').split(':'):
if os.path.exists(os.path.expanduser(path)):
self.path_combo.addItem(path)
l2.addWidget(self.path_combo)
l.addLayout(l2)
l3=QHBoxLayout()
ab=QPushButton('Create Link')
ab.setDefault(True)
cb=QPushButton('Don\'t Create')
l3.addStretch(1)
l3.addWidget(cb, 0)
l3.addWidget(ab, 0)
l.addLayout(l3)
text.setWordWrap(True)
QObject.connect(cb, SIGNAL('clicked()'), self.reject)
QObject.connect(ab, SIGNAL('clicked()'), self.accept)
def GetSelectedPath(self):
return str(self.path_combo.currentText())
def _CreateLinks(bin_dir, sel_dir):
for bin in ('ost', 'dng',):
if os.path.exists(os.path.join(sel_dir, bin)):
os.unlink(os.path.join(sel_dir, bin))
os.system('ln -s "%s" "%s"' % (os.path.join(bin_dir, bin),
os.path.join(sel_dir, bin)))
def InstallTerminalPrograms():
"""
Installs symlinks to the 'ost' and 'dng' command line programs into a
user-specified directory in the path.
"""
term_use=TerminalUsageDialog()
if term_use.exec_():
prefix=ost.GetPrefixPath()
bin_dir=os.path.join(prefix, 'bin')
sel_path=term_use.GetSelectedPath()
if not os.access(sel_path, os.W_OK):
admin_rights=AdminRights()
if admin_rights.Acquire():
for bin in ('ost', 'dng'):
admin_rights.CreateLink(os.path.join(bin_dir, bin),
os.path.join(sel_path, bin))
admin_rights.Release()
else:
_CreateLinks(bin_dir, sel_path)
...@@ -28,7 +28,7 @@ from ost.gui import FileLoader ...@@ -28,7 +28,7 @@ from ost.gui import FileLoader
from ost.gui.scene.file_loader import GenericLoader from ost.gui.scene.file_loader import GenericLoader
from ost.gui.scene.loader_manager_widget import LoaderManagerWidget from ost.gui.scene.loader_manager_widget import LoaderManagerWidget
from ost.gui.init_splash import _InitSplash from ost.gui.init_splash import _InitSplash
from ost.gui.dng import termuse
class InitMenuBar(QtCore.QObject): class InitMenuBar(QtCore.QObject):
def __init__(self, menu_bar=None): def __init__(self, menu_bar=None):
QtCore.QObject.__init__(self, menu_bar) QtCore.QObject.__init__(self, menu_bar)
...@@ -50,6 +50,11 @@ class InitMenuBar(QtCore.QObject): ...@@ -50,6 +50,11 @@ class InitMenuBar(QtCore.QObject):
webpage.setShortcut('Ctrl+D') webpage.setShortcut('Ctrl+D')
self.connect(webpage, QtCore.SIGNAL('triggered()'), self.OpenDocs) self.connect(webpage, QtCore.SIGNAL('triggered()'), self.OpenDocs)
help.addAction(webpage) help.addAction(webpage)
if sys.platform=='darwin':
install_ctl=QtGui.QAction('Install Command Line Tool', self)
self.connect(install_ctl, QtCore.SIGNAL('triggered()'),
termuse.InstallTerminalPrograms)
help.addAction(install_ctl)
about = QtGui.QAction('&About', self) about = QtGui.QAction('&About', self)
about.setStatusTip('About') about.setStatusTip('About')
about.setShortcut('Ctrl+A') about.setShortcut('Ctrl+A')
......
...@@ -22,6 +22,6 @@ class SplashDialog(QtGui.QDialog): ...@@ -22,6 +22,6 @@ class SplashDialog(QtGui.QDialog):
def _InitSplash(): def _InitSplash():
splash = SplashDialog(gui.GostyApp.Instance().perspective.main_area.qobject) splash = SplashDialog(gui.GostyApp.Instance().perspective.main_area.qobject)
splash.showNormal() splash.exec_()
#QtCore.QTimer.singleShot(30000, splash.close); #QtCore.QTimer.singleShot(30000, splash.close);
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include <boost/python.hpp> #include <boost/python.hpp>
#include <QString> #include <QString>
#include <ost/config.hh> #include <ost/config.hh>
#include <ost/gui/admin.hh>
using namespace boost::python; using namespace boost::python;
void export_AlignmentView(); void export_AlignmentView();
...@@ -97,6 +97,7 @@ namespace { ...@@ -97,6 +97,7 @@ namespace {
} }
using namespace ost::gui;
BOOST_PYTHON_MODULE(_gui) BOOST_PYTHON_MODULE(_gui)
{ {
...@@ -131,4 +132,10 @@ BOOST_PYTHON_MODULE(_gui) ...@@ -131,4 +132,10 @@ BOOST_PYTHON_MODULE(_gui)
export_overlay(); export_overlay();
export_overlay_manager(); export_overlay_manager();
#endif #endif
class_<AdminRights>("AdminRights", init<>())
.def("Acquire", &AdminRights::Acquire)
.def("Release", &AdminRights::Release)
.def("CreateLink", &AdminRights::CreateLink)
;
} }
...@@ -169,6 +169,7 @@ gl_canvas.hh ...@@ -169,6 +169,7 @@ gl_canvas.hh
gl_win.hh gl_win.hh
scene_menu.hh scene_menu.hh
gosty_app.hh gosty_app.hh
admin.hh
main.hh main.hh
main_area.hh main_area.hh
module_config.hh module_config.hh
...@@ -204,6 +205,7 @@ main_window.cc ...@@ -204,6 +205,7 @@ main_window.cc
gl_win.cc gl_win.cc
scene_menu.cc scene_menu.cc
widget.cc widget.cc
admin.cc
widget_pool.cc widget_pool.cc
remote_site_loader.cc remote_site_loader.cc
sequence_viewer/align_properties_painter.cc sequence_viewer/align_properties_painter.cc
...@@ -458,7 +460,9 @@ if (ENABLE_SPNAV) ...@@ -458,7 +460,9 @@ if (ENABLE_SPNAV)
input/spnav_input.hh input/spnav_input.hh
) )
endif() endif()
if (APPLE)
set(ADDITIONAL_LIBRARIES "-framework Security")
endif()
set(QT_USE_QTOPENGL 1) set(QT_USE_QTOPENGL 1)
set(QT_USE_QTNETWORK 1) set(QT_USE_QTNETWORK 1)
include(${QT_USE_FILE}) include(${QT_USE_FILE})
...@@ -474,7 +478,13 @@ module(NAME gui SOURCES ${OST_GUI_MOCS} ${OST_GUI_SOURCES} ...@@ -474,7 +478,13 @@ module(NAME gui SOURCES ${OST_GUI_MOCS} ${OST_GUI_SOURCES}
${OST_GUI_DATA_VIEWER_HEADERS} ${OST_GUI_DATA_VIEWER_HEADERS}
${OST_GUI_HEADERS} ${OST_GUI_HEADERS}
DEPENDS_ON gfx io mol_alg seq_alg DEPENDS_ON gfx io mol_alg seq_alg
LINK ${QT_LIBRARIES} ${PYTHON_LIBRARIES} ${BOOST_PYTHON_LIBRARIES} ${SPNAV_LIBRARIES}) LINK ${QT_LIBRARIES} ${PYTHON_LIBRARIES} ${BOOST_PYTHON_LIBRARIES}
${SPNAV_LIBRARIES})
if (ADDITIONAL_LIBRARIES)
target_link_libraries(ost_gui "${ADDITIONAL_LIBRARIES}")
endif()
include_directories(${PYTHON_INCLUDE_PATH}) include_directories(${PYTHON_INCLUDE_PATH})
qt4_add_resources(OST_QT_RESOURCE dngr.qrc) qt4_add_resources(OST_QT_RESOURCE dngr.qrc)
qt4_wrap_cpp(OST_GOSTY_MOC "gosty.hh") qt4_wrap_cpp(OST_GOSTY_MOC "gosty.hh")
......
//------------------------------------------------------------------------------
// This file is part of the OpenStructure project <www.openstructure.org>
//
// Copyright (C) 2008-2010 by the OpenStructure authors
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 3.0 of the License, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//------------------------------------------------------------------------------
#include "admin.hh"
namespace ost { namespace gui {
#if defined(__APPLE__)
AdminRights::AdminRights(): auth_(NULL)
{
}
AdminRights::~AdminRights()
{
this->Release();
}
bool AdminRights::Acquire()
{
// Connect to Authorization Services.
if (AuthorizationCreate(NULL, NULL, 0, &auth_)!=noErr) {
return false;
}
static const AuthorizationFlags kFlags =
kAuthorizationFlagInteractionAllowed
| kAuthorizationFlagExtendRights;
AuthorizationItem kActionRight = { "", 0, 0, 0 };
AuthorizationRights kRights = { 1, &kActionRight };
assert(gAuthorization != NULL);
// Request the application-specific right.
return noErr==AuthorizationCopyRights(auth_, &kRights, NULL, kFlags, NULL);
}
void AdminRights::Release()
{
if (auth_) {
AuthorizationFree(auth_, kAuthorizationFlagDestroyRights);
auth_=NULL;
}
}
void AdminRights::CreateLink(const String& from, const String& to)
{
static const char* minus_s="-s";
// const_casts are gross, but at least that way we keep gcc happy
char* const args[]={
const_cast<char*>(minus_s),
const_cast<char*>(from.c_str()),
const_cast<char*>(to.c_str()),
NULL
};
AuthorizationExecuteWithPrivileges(auth_, "/bin/ln",
kAuthorizationFlagDefaults,
args, NULL);
}
#else
AdminRights::AdminRights()
{ }
void AdminRights::CreateLink(const String& from, const String& to)
{
}
AdminRights::~AdminRights()
{ }
bool AdminRights::Acquire()
{ }
void AdminRights::Release()
{ }
#endif
}}
//------------------------------------------------------------------------------
// This file is part of the OpenStructure project <www.openstructure.org>
//
// Copyright (C) 2008-2010 by the OpenStructure authors
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 3.0 of the License, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//------------------------------------------------------------------------------
#ifndef OST_GUI_ADMIN_HH
#define OST_GUI_ADMIN_HH
#include <ost/gui/module_config.hh>
#if defined(__APPLE__)
#include <Security/Security.h>
#endif
namespace ost { namespace gui {
class DLLEXPORT_OST_GUI AdminRights {
public:
AdminRights();
~AdminRights();
bool Acquire();
void CreateLink(const String& from, const String& to);
void Release();
private:
#if defined(__APPLE__)
AuthorizationRef auth_;
#endif
};
}}
#endif
...@@ -18,7 +18,7 @@ from ost.gui.init_menubar import _InitMenuBar ...@@ -18,7 +18,7 @@ from ost.gui.init_menubar import _InitMenuBar
from ost.gui.init_spacenav import _InitSpaceNav from ost.gui.init_spacenav import _InitSpaceNav
from ost.gui.init_context_menu import _InitContextMenu from ost.gui.init_context_menu import _InitContextMenu
from ost.gui.init_splash import _InitSplash from ost.gui.init_splash import _InitSplash
from ost.gui.dng import termuse
def _InitRuleBasedBuilder(): def _InitRuleBasedBuilder():
compound_lib_path=os.path.join(ost.GetSharedDataPath(), 'compounds.chemlib') compound_lib_path=os.path.join(ost.GetSharedDataPath(), 'compounds.chemlib')
if os.path.exists(compound_lib_path): if os.path.exists(compound_lib_path):
...@@ -56,6 +56,7 @@ def _InitPanels(app): ...@@ -56,6 +56,7 @@ def _InitPanels(app):
return False return False
return True return True
def _InitFrontEnd(): def _InitFrontEnd():
_CheckRestore() _CheckRestore()
app=gui.GostyApp.Instance() app=gui.GostyApp.Instance()
...@@ -64,6 +65,11 @@ def _InitFrontEnd(): ...@@ -64,6 +65,11 @@ def _InitFrontEnd():
_InitMenuBar(app) _InitMenuBar(app)
if not _InitPanels(app): if not _InitPanels(app):
_InitSplash() _InitSplash()
if sys.platform=='darwin':
settings=QtCore.QSettings()
if not settings.value('install/clt', False).toBool():
settings.setValue('install/clt', QtCore.QVariant(True))
termuse.InstallTerminalPrograms()
_InitSpaceNav(app) _InitSpaceNav(app)
_InitContextMenu(app) _InitContextMenu(app)
main_area.AddPersistentWidget("3D Scene", "gl_win" , app.gl_win, int(QtCore.Qt.WindowMaximized)) main_area.AddPersistentWidget("3D Scene", "gl_win" , app.gl_win, int(QtCore.Qt.WindowMaximized))
...@@ -72,6 +78,7 @@ def _InitFrontEnd(): ...@@ -72,6 +78,7 @@ def _InitFrontEnd():
for module_name in additional_modules: for module_name in additional_modules:
__import__(module_name) __import__(module_name)
app.ProcessEvents() app.ProcessEvents()
_InitInspector(app) _InitInspector(app)
def _load_files(): def _load_files():
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment