From 2fe743cc70a9e7a9a87bba5e4b16c9edf5f76efd Mon Sep 17 00:00:00 2001 From: Marco Biasini <marco.biasini@unibas.ch> Date: Tue, 5 Mar 2013 11:53:43 +0100 Subject: [PATCH] implement remote loader logic in Python The code becomes much simpler, cleaner and fixes as weird crash with Qt 4.8 --- modules/gui/pymod/CMakeLists.txt | 7 +- modules/gui/pymod/dng/init.py | 5 +- modules/gui/pymod/dng/menu.py | 2 - modules/gui/pymod/export_file_loader.cc | 36 --- .../gui/pymod/export_remote_site_loader.cc | 76 ------- modules/gui/pymod/init_menubar.py | 14 -- modules/gui/pymod/scene/file_loader.py | 3 +- .../gui/pymod/scene/loader_info_handler.py | 60 ----- modules/gui/pymod/scene/loader_list_model.py | 156 ------------- .../gui/pymod/scene/loader_manager_widget.py | 199 ----------------- modules/gui/pymod/scene/remote.py | 78 +++++++ modules/gui/pymod/wrap_gui.cc | 2 - modules/gui/src/CMakeLists.txt | 7 - modules/gui/src/file_loader.cc | 31 --- modules/gui/src/file_loader.hh | 5 - modules/gui/src/loader_manager.cc | 112 ---------- modules/gui/src/loader_manager.hh | 59 ----- modules/gui/src/remote_loader.cc | 208 ------------------ modules/io/pymod/CMakeLists.txt | 2 +- modules/io/pymod/__init__.py | 33 +-- modules/io/pymod/remote.py | 93 ++++++++ 21 files changed, 181 insertions(+), 1007 deletions(-) delete mode 100644 modules/gui/pymod/export_remote_site_loader.cc delete mode 100644 modules/gui/pymod/scene/loader_info_handler.py delete mode 100644 modules/gui/pymod/scene/loader_list_model.py delete mode 100644 modules/gui/pymod/scene/loader_manager_widget.py create mode 100644 modules/gui/pymod/scene/remote.py delete mode 100644 modules/gui/src/loader_manager.cc delete mode 100644 modules/gui/src/loader_manager.hh delete mode 100644 modules/gui/src/remote_loader.cc create mode 100644 modules/io/pymod/remote.py diff --git a/modules/gui/pymod/CMakeLists.txt b/modules/gui/pymod/CMakeLists.txt index 522f66443..87a9c6337 100644 --- a/modules/gui/pymod/CMakeLists.txt +++ b/modules/gui/pymod/CMakeLists.txt @@ -6,7 +6,6 @@ set(OST_GUI_PYMOD_SOURCES export_tool.cc export_py_shell.cc export_gosty.cc - export_remote_site_loader.cc export_scene_win.cc export_sequence_viewer.cc export_perspective.cc @@ -37,6 +36,7 @@ init_inspector.py inspector_widget.py map_level_widget.py preset.py +remote.py preset_editor_list_model.py preset_editor_widget.py preset_info_handler.py @@ -54,11 +54,6 @@ trace_widget.py tube_widget.py uniform_color_widget.py visibility_op.py -file_loader.py -loader_info_handler.py -loader_list_model.py -loader_manager_widget.py -immutable_loader_info_handler.py line_trace_widget.py wireframe_widget.py query_editor.py diff --git a/modules/gui/pymod/dng/init.py b/modules/gui/pymod/dng/init.py index e2338deed..ffe73d8b7 100644 --- a/modules/gui/pymod/dng/init.py +++ b/modules/gui/pymod/dng/init.py @@ -23,6 +23,8 @@ from ost.gui.init_context_menu import _InitContextMenu from ost.gui.init_splash import _InitSplash from ost.gui.dng import termuse from ost.gui.dng import superpositiondialog +from ost.gui.scene.remote import RemoteLoader + import ost.gui.dng.menu from PyQt4.QtGui import * def _my_exit(code): @@ -56,7 +58,6 @@ def _InitPanels(app): panels = app.perspective.panels panels.AddWidgetToPool('ost.gui.FileBrowser', -1) panels.AddWidgetToPool('ost.gui.PythonShell', 1) - panels.AddWidgetToPool('ost.gui.RemoteLoader', -1) panels.AddWidgetToPool('ost.gui.SceneWin', 1) panels.AddWidgetToPool('ost.gui.SequenceViewer', 1) panels.AddWidgetToPool('ost.gui.MessageWidget', 1) @@ -64,8 +65,6 @@ def _InitPanels(app): panels.AddWidget(gui.PanelPosition.LEFT_PANEL, app.scene_win) panels.AddWidgetByName(gui.PanelPosition.LEFT_PANEL, 'ost.gui.FileBrowser', False) - panels.AddWidgetByName(gui.PanelPosition.LEFT_PANEL, - 'ost.gui.RemoteLoader', False) panels.AddWidget(gui.PanelPosition.BOTTOM_PANEL, app.seq_viewer) panels.AddWidget(gui.PanelPosition.BOTTOM_PANEL, app.py_shell) panels.AddWidget(gui.PanelPosition.RIGHT_PANEL, app.message_widget) diff --git a/modules/gui/pymod/dng/menu.py b/modules/gui/pymod/dng/menu.py index 75d2ae2ba..800c3f805 100644 --- a/modules/gui/pymod/dng/menu.py +++ b/modules/gui/pymod/dng/menu.py @@ -2,7 +2,6 @@ from PyQt4.QtCore import * from PyQt4.QtGui import * from ost import * from ost import gui -from ost.gui.scene.loader_manager_widget import LoaderManagerWidget from ost.gui.init_splash import _InitSplash from ost.gui.dng import termuse from ost.gui.dng import superpositiondialog @@ -204,7 +203,6 @@ class WindowMenu(QMenu): def __init__(self, parent=None): QMenu.__init__(self, parent) self.setTitle('Window') - self.loader_manager=LoaderManagerWidget() gosty=gui.GostyApp.Instance() QObject.connect(self, SIGNAL('aboutToShow()'), self._AboutToShow) inspector_visible=gosty.GetWidget('InspectorDialog').isVisible() diff --git a/modules/gui/pymod/export_file_loader.cc b/modules/gui/pymod/export_file_loader.cc index ab978f09a..b39d6dadd 100644 --- a/modules/gui/pymod/export_file_loader.cc +++ b/modules/gui/pymod/export_file_loader.cc @@ -24,7 +24,6 @@ using namespace boost::python; #include <QString> #include <ost/gui/file_loader.hh> -#include <ost/gui/loader_manager.hh> using namespace ost; using namespace ost::gui; @@ -41,48 +40,13 @@ void load_object_b(const QString& file_name, const QString& selection) FileLoader::LoadObject(file_name, selection); } -void load_from_site_a(const QString& id) -{ - FileLoader::LoadFrom(id); -} - -void load_from_site_b(const QString& id, const QString& site) -{ - FileLoader::LoadFrom(id,site); -} - -void load_from_site_c(const QString& id, const QString& site, const QString& selection) -{ - FileLoader::LoadFrom(id,site,selection); -} - -void add_remote_site_loader(LoaderManager* loader_manager, const QString& site, RemoteSiteLoader* site_loader){ - loader_manager->AddRemoteSiteLoader(site,site_loader); -} - } void export_FileLoader() { - class_<LoaderManager, LoaderManagerPtr, boost::noncopyable>("LoaderManager", no_init) - .def("GetSiteLoaderIdents", &LoaderManager::GetSiteLoaderIdents) - .def("AddRemoteSiteLoader", &add_remote_site_loader) - .def("RemoveRemoteSiteLoader", &LoaderManager::RemoveRemoteSiteLoader) - .def("SetDefaultRemoteSiteIdent", &LoaderManager::SetDefaultRemoteSiteIdent) - .def("GetDefaultRemoteSiteIdent", &LoaderManager::GetDefaultRemoteSiteIdent) - ; - class_<FileLoader, boost::noncopyable>("FileLoader", no_init) .def("LoadObject", &load_object_a) .def("LoadObject", &load_object_b) .staticmethod("LoadObject") - .def("LoadFrom", &load_from_site_a) - .def("LoadFrom", &load_from_site_b) - .def("LoadFrom", &load_from_site_c) - .staticmethod("LoadFrom") - .def("GetSiteLoaderIdents", &FileLoader::GetSiteLoaderIdents) - .staticmethod("GetSiteLoaderIdents") - .def("GetLoaderManager", &FileLoader::GetLoaderManager) - .staticmethod("GetLoaderManager") ; } diff --git a/modules/gui/pymod/export_remote_site_loader.cc b/modules/gui/pymod/export_remote_site_loader.cc deleted file mode 100644 index 80ad57049..000000000 --- a/modules/gui/pymod/export_remote_site_loader.cc +++ /dev/null @@ -1,76 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the OpenStructure project <www.openstructure.org> -// -// Copyright (C) 2008-2011 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 <boost/python.hpp> -#include <string> - - -#include <ost/gui/remote_site_loader.hh> -#include <boost/python/register_ptr_to_python.hpp> -#include <boost/python/suite/indexing/vector_indexing_suite.hpp> - -#include "sip_handler.hh" - -using namespace ost; -using namespace ost::gui; -using namespace boost::python; - -struct WrappedRemoteSiteLoader : public RemoteSiteLoader -{ - WrappedRemoteSiteLoader(PyObject *p): - RemoteSiteLoader(), self(p) - { } - - virtual void LoadById(const QString& id, const QString& selection=QString()){ - return call_method<void, std::string>(self, "LoadById", id.toStdString(), selection.toStdString()); - } - - virtual QString GetRemoteSiteName(){ - return call_method<QString>(self, "GetRemoteSiteName"); - } - - virtual bool IsImg() const{ - return call_method<bool>(self, "IsImg"); - } - - virtual QNetworkReply* ById(const QString& id, const QString& selection=QString()){ - object obj = call_method<object, std::string, std::string>(self, "ById", id.toStdString(), selection.toStdString()); - QNetworkReply* network_reply= get_cpp_qobject<QNetworkReply>(obj); - if(network_reply){ - return network_reply; - } - return NULL; - } - - private: - PyObject* self; -}; - -void export_RemoteSiteLoader() -{ - class_<RemoteSiteLoader, WrappedRemoteSiteLoader, boost::noncopyable>("RemoteSiteLoader") - .def("LoadById",&WrappedRemoteSiteLoader::LoadById) - .def("GetRemoteSiteName", &WrappedRemoteSiteLoader::GetRemoteSiteName) - .def("IsImg", &WrappedRemoteSiteLoader::IsImg) - ; - -} - - - diff --git a/modules/gui/pymod/init_menubar.py b/modules/gui/pymod/init_menubar.py index cc8dd3b61..761e483bb 100644 --- a/modules/gui/pymod/init_menubar.py +++ b/modules/gui/pymod/init_menubar.py @@ -25,8 +25,6 @@ import ost from PyQt4 import QtCore, QtGui from ost.gui import FileLoader -from ost.gui.scene.file_loader import GenericLoader -from ost.gui.scene.loader_manager_widget import LoaderManagerWidget from ost.gui.init_splash import _InitSplash from ost.gui.dng import termuse class InitMenuBar(QtCore.QObject): @@ -74,15 +72,6 @@ class InitMenuBar(QtCore.QObject): self.connect(reset, QtCore.SIGNAL('triggered()'), self.ResetView) window.addAction(reset) - #Options - #Add file loader to menu - loader_manager = QtGui.QAction('File &Loader', self) - loader_manager.setStatusTip('Loader Manager') - self.connect(loader_manager, QtCore.SIGNAL('triggered()'), self.LoaderManager) - options.addAction(loader_manager) - - self.loader_manager = LoaderManagerWidget() - def Exit(self): reply = QtGui.QMessageBox() reply.addButton(QtGui.QMessageBox.Yes) @@ -93,9 +82,6 @@ class InitMenuBar(QtCore.QObject): if(QtCore.QFileInfo(filename).isFile()): FileLoader.LoadObject(str(filename)) - def LoaderManager(self): - self.loader_manager.exec_() - def OpenDocs(self): QtGui.QDesktopServices.openUrl(QtCore.QUrl("http://www.openstructure.org/docs/")) diff --git a/modules/gui/pymod/scene/file_loader.py b/modules/gui/pymod/scene/file_loader.py index ba7efb375..a0acf4140 100644 --- a/modules/gui/pymod/scene/file_loader.py +++ b/modules/gui/pymod/scene/file_loader.py @@ -26,7 +26,7 @@ import re from PyQt4 import QtCore, QtGui, QtNetwork from ost.gui import FileLoader - +""" class BaseRemoteLoader(gui.RemoteSiteLoader): def __init__(self): gui.RemoteSiteLoader.__init__(self) @@ -195,3 +195,4 @@ class GenericLoader(BaseRemoteLoader): default = bool(int(group.GetAttribute(GenericLoader.DEFAULT_ATTRIBUTE_NAME))) return GenericLoader(name, url, up_case, file_type, tmp_url, img, default) +""" diff --git a/modules/gui/pymod/scene/loader_info_handler.py b/modules/gui/pymod/scene/loader_info_handler.py deleted file mode 100644 index 079620ecc..000000000 --- a/modules/gui/pymod/scene/loader_info_handler.py +++ /dev/null @@ -1,60 +0,0 @@ -#------------------------------------------------------------------------------ -# This file is part of the OpenStructure project <www.openstructure.org> -# -# Copyright (C) 2008-2011 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 -#------------------------------------------------------------------------------ -# -*- coding: utf-8 -*- - -from ost import gui -from ost import gfx -from ost import info -from PyQt4 import QtCore, QtGui -from immutable_loader_info_handler import ImmutableLoaderInfoHandler - -#Generic Loader Info Handler -class LoaderInfoHandler(ImmutableLoaderInfoHandler): - - def __init__(self, file_name): - ImmutableLoaderInfoHandler.__init__(self, file_name) - - def StoreLoader(self,name, loader): - group = self.loaders_.CreateGroup(ImmutableLoaderInfoHandler.LOADER_GROUP_NAME) - group.SetAttribute(ImmutableLoaderInfoHandler.NAME_ATTRIBUTE_NAME, str(name)) - loader.ToInfo(group) - self.handle_.Export(self.file_name_) - - def RemoveLoader(self, name): - group_list = self.loaders_.GetGroups(ImmutableLoaderInfoHandler.LOADER_GROUP_NAME) - group_to_del = None - for group in group_list: - if group.HasAttribute(ImmutableLoaderInfoHandler.NAME_ATTRIBUTE_NAME): - groupname = group.GetAttribute(ImmutableLoaderInfoHandler.NAME_ATTRIBUTE_NAME) - if name == groupname: - group_to_del = group - break - - if group_to_del != None: - self.loaders_.Remove(group_to_del) - self.handle_.Export(self.file_name_) - - def RenameLoader(self, old, new): - group_list = self.loaders_.GetGroups(ImmutableLoaderInfoHandler.LOADER_GROUP_NAME) - for group in group_list: - if group.HasAttribute(ImmutableLoaderInfoHandler.NAME_ATTRIBUTE_NAME): - groupname = group.GetAttribute(ImmutableLoaderInfoHandler.NAME_ATTRIBUTE_NAME) - if old == groupname: - group.SetAttribute(ImmutableLoaderInfoHandler.NAME_ATTRIBUTE_NAME, new) - self.handle_.Export(self.file_name_) \ No newline at end of file diff --git a/modules/gui/pymod/scene/loader_list_model.py b/modules/gui/pymod/scene/loader_list_model.py deleted file mode 100644 index c033df038..000000000 --- a/modules/gui/pymod/scene/loader_list_model.py +++ /dev/null @@ -1,156 +0,0 @@ -from ost import gui -from ost import gfx -import os -import ost -from PyQt4 import QtCore, QtGui -from immutable_loader_info_handler import ImmutableLoaderInfoHandler -from loader_info_handler import LoaderInfoHandler -from ost.gui import LoaderManager - -class LoaderListModel(QtCore.QAbstractListModel): - - IMMUTABLE_LOADERS_PATH = os.path.join(ost.GetSharedDataPath(),"scene", - "loaders.xml") - MUTABLE_LOADERS_PATH = "user_loaders.xml" - - def __init__(self, parent=None, *args): - QtCore.QAbstractListModel.__init__(self, parent, *args) - - self.data_ = list() - - #Info Handler - self.immutable_infoh_ = ImmutableLoaderInfoHandler(LoaderListModel.IMMUTABLE_LOADERS_PATH) - self.infoh_ = LoaderInfoHandler(LoaderListModel.MUTABLE_LOADERS_PATH) - self.LoadLoaderFromInfo() - - self.loader_manager_ = gui.FileLoader.GetLoaderManager() - - def AddItem(self, name, loader, row, editable, save): - if self.NameIsValid(name): - self.insertRow(row, QtCore.QModelIndex()) - self.data_[row] = [name, loader, editable] - model_index = self.createIndex(row,0) - index = self.index(row) - end_index = self.createIndex(self.rowCount(),0) - if save: - self.AddLoaderToInfo(name, loader) - self.emit(QtCore.SIGNAL("dataChanged"),model_index, end_index) - gui.FileLoader.GetLoaderManager().AddRemoteSiteLoader(name, loader) - if(loader.IsDefault()): - gui.FileLoader.GetLoaderManager().SetDefaultRemoteSiteIdent(name) - return True - return False - - def IsEditable(self, row): - return self.data_[row][2] - - def RemoveItem(self, row): - if self.IsEditable(row): - name = self.data_[row][0] - self.removeRow(row, QtCore.QModelIndex()) - model_index = self.createIndex(row,0) - self.infoh_.RemoveLoader(name) - self.emit(QtCore.SIGNAL("dataChanged"),model_index, model_index) - self.loader_manager_.RemoveRemoteSiteLoader(name) - return True - return False - - def AddLoaderToInfo(self, name, loader): - self.infoh_.StoreLoader(name, loader) - - def RemoveLoaderFromInfo(self, name): - self.infoh_.RemoveLoader(name) - - def SetItem(self, model_index, loader): - row = model_index.row() - name = self.data_[row][0] - self.data_[row][1] = loader - model_index = self.createIndex(row,0) - index = self.index(row) - end_index = self.createIndex(self.rowCount(),0) - self.RemoveLoaderFromInfo(self.data_[row][0]) - self.AddLoaderToInfo(self.data_[row][0], loader) - self.emit(QtCore.SIGNAL("dataChanged"),model_index, end_index) - self.loader_manager_.RemoveRemoteSiteLoader(name) - self.loader_manager_.AddRemoteSiteLoader(name, loader) - return True - - def LoadLoaderFromInfo(self): - if self.immutable_infoh_: - loaders = self.immutable_infoh_.GetLoaders() - for k, v in loaders.iteritems(): - self.AddItem(k, v, self.GetLastRow(), False, False) - - loaders = self.infoh_.GetLoaders() - for k, v in loaders.iteritems(): - self.AddItem(k, v, self.GetLastRow(), True, False) - - def GetLoader(self, model_index): - if model_index.isValid(): - return self.data_[model_index.row()][1] - - def GetLastRow(self): - return self.rowCount() - - #Helper - def NameIsValid(self, string): - if len(string)==0: - return False - for values in self.data_: - if string == values[0]: - return False - return True - - #Overwritten Methods - def rowCount(self, parent=QtCore.QModelIndex()): - return len(self.data_) - - def data(self, index, role): - if index.isValid() and index.row()< self.rowCount(): - data = self.data_[index.row()] - if role == QtCore.Qt.DisplayRole: - return QtCore.QVariant(data[0]) - return QtCore.QVariant() - - def setData(self, index, value, role): - if index.isValid(): - row = index.row() - if not self.data_[row]: - self.data_[row] = list() - if role == QtCore.Qt.EditRole and self.NameIsValid(value.toString()): - old_name = str(self.data_[row][0]) - new_name = value.toString() - self.data_[row][0] = new_name - self.infoh_.RenameLoader(old_name,str(new_name)) - self.emit(QtCore.SIGNAL("dataChanged"),index, index) - self.loader_manager_.RemoveRemoteSiteLoader(old_name) - self.loader_manager_.AddRemoteSiteLoader(str(new_name), self.data_[row][1]) - return True - elif role == QtCore.Qt.DisplayRole: - self.data_[row][0] = value.toString() - return False - - def flags(self, index): - if index.isValid(): - flags = QtCore.QAbstractItemModel.flags(self,index) - if self.IsEditable(index.row()): - return flags | QtCore.Qt.ItemIsEditable - else: - return flags - return QtCore.Qt.ItemIsEnabled - - def insertRow(self, position, index): - self.beginInsertRows(index, position, position) - self.data_.insert(position,list()) - self.endInsertRows() - return True - - def removeRow(self, position, index): - self.beginRemoveRows(index, position, position) - del self.data_[position] - self.endRemoveRows() - return True - - - - diff --git a/modules/gui/pymod/scene/loader_manager_widget.py b/modules/gui/pymod/scene/loader_manager_widget.py deleted file mode 100644 index d1fd7795d..000000000 --- a/modules/gui/pymod/scene/loader_manager_widget.py +++ /dev/null @@ -1,199 +0,0 @@ -#------------------------------------------------------------------------------ -# This file is part of the OpenStructure project <www.openstructure.org> -# -# Copyright (C) 2008-2011 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 -#------------------------------------------------------------------------------ -# -*- coding: utf-8 -*- - -import os -import ost -from ost import gui -from ost import gfx -from datetime import datetime -from PyQt4 import QtCore, QtGui - -from loader_list_model import LoaderListModel -from file_loader import GenericLoader - -#Gradient Preset Widget -class LoaderManagerWidget(QtGui.QDialog): - ICONS_DIR = os.path.join(ost.GetSharedDataPath(), "gui", "icons/") - def __init__(self, parent=None): - QtGui.QDialog.__init__(self, parent) - - #Title - self.text_ = "Loader Manager" - - #Create Ui elements - self.list_view_ = QtGui.QListView() - - #Create Model - self.list_model_ = LoaderListModel(self) - self.list_view_.setModel(self.list_model_) - self.list_view_.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) - - loader_label = QtGui.QLabel(self.text_) - font = loader_label.font() - font.setBold(True) - - self.add_action = QtGui.QAction("+",self) - self.add_action.setIcon(QtGui.QIcon(LoaderManagerWidget.ICONS_DIR+"add_icon.png")) - - QtCore.QObject.connect(self.add_action, QtCore.SIGNAL("triggered()"), self.Add) - - self.add_button_ = QtGui.QToolButton(self) - self.add_button_.setIconSize(QtCore.QSize(20,20)) - self.add_button_.setDefaultAction(self.add_action) - - grid = QtGui.QGridLayout() - grid.setContentsMargins(0,5,0,0) - grid.addWidget(loader_label, 0, 0, 1, 1) - qhbox = QtGui.QHBoxLayout() - grid.addWidget(self.list_view_,1,0,3,3) - grid.addWidget(self.add_button_,4,0,1,1) - self.setLayout(grid) - - self.list_view_.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - QtCore.QObject.connect(self.list_view_, QtCore.SIGNAL("customContextMenuRequested(const QPoint)"), self.contextMenuEvent) - self.CreateContextMenu() - - QtCore.QObject.connect(self.list_view_, QtCore.SIGNAL("doubleClicked(const QModelIndex)"), self.Edit) - - def CreateContextMenu(self): - self.contextMenu_ = QtGui.QMenu("Context menu", self) - self.remove_ = QtGui.QAction("Remove", self.list_view_) - self.rename_ = QtGui.QAction("Rename", self.list_view_) - self.edit_ = QtGui.QAction("Edit", self.list_view_) - self.contextMenu_.addAction(self.remove_) - self.contextMenu_.addAction(self.rename_) - self.contextMenu_.addAction(self.edit_) - #Connect Signals with Slots - QtCore.QObject.connect(self.remove_, QtCore.SIGNAL("triggered()"), self.Remove) - QtCore.QObject.connect(self.rename_, QtCore.SIGNAL("triggered()"), self.Rename) - QtCore.QObject.connect(self.edit_, QtCore.SIGNAL("triggered()"), self.Edit) - - def contextMenuEvent(self, pos): - #ContextMenu - index = self.list_view_.indexAt(pos) - if index.isValid(): - if self.list_model_.IsEditable(index.row()): - self.contextMenu_.popup(QtGui.QCursor.pos()) - - def Add(self): - row = self.list_model_.GetLastRow() - edit_widget = LoaderEditWidget() - - if edit_widget.exec_() and self.list_model_.AddItem(datetime.now().isoformat(' '), edit_widget.GetLoader(), row, True, True): - index = self.list_model_.index(row) - self.list_view_.setCurrentIndex(index) - self.Rename() - - def Edit(self): - current_index = self.list_view_.currentIndex() - loader = self.list_model_.GetLoader(current_index) - edit_widget = LoaderEditWidget() - edit_widget.SetLoader(loader) - if edit_widget.exec_(): - self.list_model_.SetItem(current_index, edit_widget.GetLoader()) - - - def Remove(self): - if(self.list_view_.currentIndex().isValid()): - ret = QtGui.QMessageBox.warning(self, "Delete File Loader", - "Delete File Loader?", - QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) - if ret == QtGui.QMessageBox.Yes: - self.list_model_.RemoveItem(self.list_view_.currentIndex().row()) - - def Rename(self): - if(self.list_view_.currentIndex().isValid()): - self.list_view_.edit(self.list_view_.currentIndex()) - - def GetText(self): - return self.text_ - - - - -class LoaderEditWidget(QtGui.QDialog): - def __init__(self, parent=None): - QtGui.QDialog.__init__(self, parent) - name_ext_label = QtGui.QLabel("Name Extension") - self.name_ext_edit_ = QtGui.QLineEdit() - - url_label = QtGui.QLabel("Url") - self.url_edit_ = QtGui.QLineEdit() - self.add_id_button_ = QtGui.QToolButton(self) - self.add_id_button_.setDefaultAction(QtGui.QAction("ID",self)) - - file_ext_label = QtGui.QLabel("File Type") - self.file_ext_auto_ = QtGui.QCheckBox("Auto") - self.file_ext_edit_ = QtGui.QLineEdit() - - self.hbox_ = QtGui.QHBoxLayout() - self.ok_button_ = QtGui.QPushButton("OK") - self.cancel_button_ = QtGui.QPushButton("Cancel") - self.hbox_.addWidget(self.ok_button_) - self.hbox_.addStretch() - self.hbox_.addWidget(self.cancel_button_) - - grid = QtGui.QGridLayout() - grid.setContentsMargins(0,5,0,0) - grid.addWidget(name_ext_label, 0, 0, 1, 1) - grid.addWidget(self.name_ext_edit_, 0, 1, 1, 4) - grid.addWidget(url_label, 1, 0, 1, 1) - grid.addWidget(self.url_edit_, 1, 1, 1, 3) - grid.addWidget(self.add_id_button_, 1, 4, 1, 1) - grid.addWidget(file_ext_label, 2, 0, 1, 1) - grid.addWidget(self.file_ext_auto_, 2, 1, 1, 1) - grid.addWidget(self.file_ext_edit_, 2, 2, 1, 3) - grid.addLayout(self.hbox_,3,0,1,2) - grid.setRowStretch(2, 1) - self.setLayout(grid) - - QtCore.QObject.connect(self.add_id_button_, QtCore.SIGNAL("clicked()"), self.AppendId) - QtCore.QObject.connect(self.file_ext_auto_, QtCore.SIGNAL("stateChanged(int)"), self.CbStateChanged) - QtCore.QObject.connect(self.ok_button_, QtCore.SIGNAL("clicked()"), self.Ok) - QtCore.QObject.connect(self.cancel_button_, QtCore.SIGNAL("clicked()"), self.Cancel) - - def GetLoader(self): - name_ext = str(self.name_ext_edit_.text()) - url = str(self.url_edit_.text()) - file_ext = None - if not self.file_ext_auto_.isChecked(): - file_ext = str(self.file_ext_edit_.text()) - - return GenericLoader(name_ext, url, False, file_ext) - - def SetLoader(self, loader): - self.name_ext_edit_.setText(loader.name_) - self.url_edit_.setText(loader.url_) - if loader.file_type_ is not None: - self.file_ext_edit_.setText(loader.file_type_) - self.file_ext_auto_.setChecked(False) - else: - self.file_ext_auto_.setChecked(True) - def AppendId(self): - self.url_edit_.setText(self.url_edit_.text()+"${ID}") - - def CbStateChanged(self, state): - self.file_ext_edit_.setEnabled(not self.file_ext_auto_.isChecked()) - - def Ok(self): - self.accept() - - def Cancel(self): - self.reject() diff --git a/modules/gui/pymod/scene/remote.py b/modules/gui/pymod/scene/remote.py new file mode 100644 index 000000000..46a7553b4 --- /dev/null +++ b/modules/gui/pymod/scene/remote.py @@ -0,0 +1,78 @@ +from PyQt4.QtCore import * +from PyQt4.QtGui import * +import threading +from ost import LogError +from ost import gui, gfx +from ost.io.remote import RemoteLoad, REMOTE_REPOSITORIES +import re + +class RemoteLoader(QWidget): + def __init__(self): + QWidget.__init__(self) + self._line = QLineEdit(self) + self._load = QToolButton(self) + self._load.setAttribute(Qt.WA_MacSmallSize) + QObject.connect(self._line, SIGNAL('returnPressed()'), + self._DoLoad) + QObject.connect(self._load, SIGNAL('clicked()'), + self._DoLoad) + hbox = QHBoxLayout(self) + hbox.addWidget(self._line,1) + hbox.addWidget(self._load,0) + self.setLayout(hbox) + hbox.setMargin(3) + hbox.setSpacing(3) + self._menu = self._RemoteMenu() + self._load.setMenu(self._menu) + self._current_repo = 'pdb' + self._UpdateLoadButton(self._current_repo) + self.setFixedHeight(self._load.height()) + self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) + + def _RemoteMenu(self): + menu = QMenu() + action_group = QActionGroup(menu) + for k,v in REMOTE_REPOSITORIES.iteritems(): + action = menu.addAction(v.name) + action.setCheckable(True) + if k == 'pdb': + action.setChecked(True) + action.setData(QVariant(k)) + action_group.addAction(action) + QObject.connect(menu, SIGNAL('triggered(QAction*)'), + self._ToggleRepo) + return menu + def _UpdateLoadButton(self, current): + name = REMOTE_REPOSITORIES[current].name + self._load.setText('load from %s ' % name) + + def _ToggleRepo(self, action): + self._current_repo = str(action.data().toString()) + self._UpdateLoadButton(self._current_repo) + + + def _DoLoad(self): + split_ids = [] + for p in str(self._line.text()).split(','): + for k in p.split(): + if len(k.strip()): + split_ids.append(k.strip()) + self._line.setText('') + for split_id in split_ids: + try: + ent = RemoteLoad(split_id, from_repo=self._current_repo) + except Exception, e: + LogError(str(e)) + continue + g = gfx.Entity(split_id, ent) + try: + gfx.Scene().Add(g) + except Exception, e: + LogError(str(e)) + +remote_loader=RemoteLoader() +remote_loader_for_panel=gui.Widget(remote_loader) +remote_loader_for_panel.qobject.setSizePolicy(QSizePolicy.Expanding, + QSizePolicy.Fixed) +panels=gui.GostyApp.Instance().perspective.panels +panels.AddWidgetToPool("Remote Loader",remote_loader_for_panel) diff --git a/modules/gui/pymod/wrap_gui.cc b/modules/gui/pymod/wrap_gui.cc index 81b6ff788..a4474a6f8 100644 --- a/modules/gui/pymod/wrap_gui.cc +++ b/modules/gui/pymod/wrap_gui.cc @@ -38,7 +38,6 @@ void export_SipHandler(); void export_SceneSelection(); void export_MainArea(); void export_MenuBar(); -void export_RemoteSiteLoader(); void export_FileLoader(); void export_FileViewer(); void export_Widget(); @@ -118,7 +117,6 @@ BOOST_PYTHON_MODULE(_ost_gui) export_SceneWin(); export_SceneSelection(); export_SequenceViewer(); - export_RemoteSiteLoader(); export_FileLoader(); export_FileViewer(); export_Widget(); diff --git a/modules/gui/src/CMakeLists.txt b/modules/gui/src/CMakeLists.txt index 190cb6f66..cdeb7d273 100644 --- a/modules/gui/src/CMakeLists.txt +++ b/modules/gui/src/CMakeLists.txt @@ -166,7 +166,6 @@ set(OST_GUI_HEADERS file_browser.hh file_type_dialog.hh file_viewer.hh -remote_loader.hh gl_canvas.hh gl_win.hh scene_menu.hh @@ -176,7 +175,6 @@ module_config.hh main.hh main_area.hh perspective.hh -remote_site_loader.hh scene_selection.hh main_window.hh dock_widget.hh @@ -188,7 +186,6 @@ widget_pool.hh widget_registry.hh widget_state_saver.hh file_loader.hh -loader_manager.hh ) set(OST_GUI_SOURCES @@ -198,7 +195,6 @@ widget_registry.cc file_browser.cc file_type_dialog.cc file_viewer.cc -remote_loader.cc main.cc gl_canvas.cc dock_widget.cc @@ -208,7 +204,6 @@ scene_menu.cc widget.cc admin.cc widget_pool.cc -remote_site_loader.cc messages/message_widget.cc messages/message_box_widget.cc messages/log_reader.cc @@ -237,7 +232,6 @@ widget_state_saver.cc scene_selection.cc widget_geom_handler.cc file_loader.cc -loader_manager.cc panels/button_bar.cc panels/drop_box.cc panels/panel_bar.cc @@ -305,7 +299,6 @@ set(HEADERS_TO_BE_MOCCED file_browser.hh file_type_dialog.hh file_viewer.hh -remote_loader.hh gl_canvas.hh gl_win.hh scene_menu.hh diff --git a/modules/gui/src/file_loader.cc b/modules/gui/src/file_loader.cc index d31c2f0b8..bc69ba7b8 100644 --- a/modules/gui/src/file_loader.cc +++ b/modules/gui/src/file_loader.cc @@ -59,7 +59,6 @@ #include <QMenuBar> namespace ost { namespace gui { -LoaderManagerPtr FileLoader::loader_manager_ = LoaderManagerPtr(); #if OST_IMG_ENABLED QList<img::ImageHandle> FileLoader::loaded_images_; @@ -161,36 +160,6 @@ gfx::GfxObjP FileLoader::NoHandlerFound(const QString& filename) return gfx::GfxObjP(); } -void FileLoader::LoadFrom(const QString& id, const QString& site, const QString& selection) -{ - if(!loader_manager_) - loader_manager_ = LoaderManagerPtr(new LoaderManager()); - RemoteSiteLoader* remote_site = loader_manager_->GetRemoteSiteLoader(site); - if(remote_site){ - remote_site->LoadById(id,selection); - } - else{ - remote_site = loader_manager_->GetCurrentSiteLoader(); - if(remote_site){ - remote_site->LoadById(id,selection); - } - } -} - -LoaderManagerPtr FileLoader::GetLoaderManager() -{ - if(!loader_manager_) - loader_manager_ = LoaderManagerPtr(new LoaderManager()); - return loader_manager_; -} - -std::vector<String> FileLoader::GetSiteLoaderIdents() -{ - if(!loader_manager_) - loader_manager_ = LoaderManagerPtr(new LoaderManager()); - return loader_manager_->GetSiteLoaderIdents(); -} - void FileLoader::HandleError(const Error& e, ErrorType type, const QString& filename, gfx::GfxObjP obj) { if(type==GFX_ADD || type==GFX_MULTIPLE_ADD){ diff --git a/modules/gui/src/file_loader.hh b/modules/gui/src/file_loader.hh index 32a4ba18e..23419b613 100644 --- a/modules/gui/src/file_loader.hh +++ b/modules/gui/src/file_loader.hh @@ -24,8 +24,6 @@ #include <ost/gfx/gfx_object.hh> #include <ost/gui/module_config.hh> -#include <ost/gui/remote_site_loader.hh> -#include <ost/gui/loader_manager.hh> #include <ost/io/io_exception.hh> #include <ost/io/entity_io_handler.hh> @@ -64,7 +62,6 @@ private: static gfx::GfxObjP NoHandlerFound(const QString& filename); virtual ~FileLoader(); - static LoaderManagerPtr loader_manager_; #if OST_IMG_ENABLED static QList<img::ImageHandle> loaded_images_; @@ -72,9 +69,7 @@ private: public: static void LoadObject(const QString& filename, const QString& selection=QString()); - static void LoadFrom(const QString& id, const QString& site=QString(), const QString& selection=QString()); static std::vector<String> GetSiteLoaderIdents(); - static LoaderManagerPtr GetLoaderManager(); }; } } diff --git a/modules/gui/src/loader_manager.cc b/modules/gui/src/loader_manager.cc deleted file mode 100644 index bfe2853dc..000000000 --- a/modules/gui/src/loader_manager.cc +++ /dev/null @@ -1,112 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the OpenStructure project <www.openstructure.org> -// -// Copyright (C) 2008-2011 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 <ost/gui/gosty_app.hh> -#include "loader_manager.hh" - -#include <ost/gui/perspective.hh> -#include <QDir> -#include <QAction> -#include <QMenu> -#include <QFileInfo> -#include <QMessageBox> -#include <QMenuBar> - - -namespace ost { namespace gui { - -LoaderManager::LoaderManager(): - site_loaders_(), - site_actions_(new QActionGroup(GostyApp::Instance()->GetPerspective()->GetMenuBar())), - default_site_() - -{ - site_actions_->setExclusive(true); -} - -void LoaderManager::AddRemoteSiteLoader(const QString& ident, RemoteSiteLoader* site_loader) -{ - site_loaders_.insert(ident,site_loader); - - QAction* action = new QAction(ident,site_actions_); - action->setCheckable(true); - site_actions_->addAction(action); - if(site_actions_->checkedAction()==NULL){ - action->setChecked(true); - } -} - -void LoaderManager::RemoveRemoteSiteLoader(const QString& ident) -{ - site_loaders_.remove(ident); - - QList<QAction*> actions = site_actions_->actions(); - QAction* action = NULL; - for (int i=0; i<actions.size(); i++){ - if(actions[i]->text()==ident){ - action = actions[i]; - break; - } - } - if(action){ - site_actions_->removeAction(action); - } -} - - -RemoteSiteLoader* LoaderManager::GetRemoteSiteLoader(const QString& ident) -{ - if(site_loaders_.contains(ident)){ - return site_loaders_[ident]; - } - return NULL; -} - -RemoteSiteLoader* LoaderManager::GetCurrentSiteLoader() -{ - if(site_actions_->checkedAction()!=NULL) - return site_loaders_[site_actions_->checkedAction()->text()]; - return NULL; -} - -std::vector<String> LoaderManager::GetSiteLoaderIdents() -{ - QList<QString> keys = site_loaders_.keys(); - std::vector<String> sites; - for(int i=0;i<keys.size();i++){ - sites.push_back(keys.at(i).toStdString()); - } - return sites; -} - -RemoteSiteLoader* LoaderManager::GetDefaultRemoteSiteLoader() -{ - return GetRemoteSiteLoader(GetDefaultRemoteSiteIdent()); -} - -QString LoaderManager::GetDefaultRemoteSiteIdent(){ - return default_site_; -} - -void LoaderManager::SetDefaultRemoteSiteIdent(const QString& ident){ - default_site_ = ident; -} - -LoaderManager::~LoaderManager(){} - -} } diff --git a/modules/gui/src/loader_manager.hh b/modules/gui/src/loader_manager.hh deleted file mode 100644 index f969b289c..000000000 --- a/modules/gui/src/loader_manager.hh +++ /dev/null @@ -1,59 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the OpenStructure project <www.openstructure.org> -// -// Copyright (C) 2008-2011 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_LOADER_MANAGER_HH -#define OST_GUI_LOADER_MANAGER_HH -#include <vector> - -#include <boost/shared_ptr.hpp> - -#include <QString> -#include <QMap> - -#include <ost/gui/remote_site_loader.hh> - -namespace ost { namespace gui { - -class DLLEXPORT_OST_GUI LoaderManager { - -public: - LoaderManager(); - virtual ~LoaderManager(); - std::vector<String> GetSiteLoaderIdents(); - void AddRemoteSiteLoader(const QString& ident, RemoteSiteLoader* site_loader); - void RemoveRemoteSiteLoader(const QString& ident); - RemoteSiteLoader* GetRemoteSiteLoader(const QString& ident); - RemoteSiteLoader* GetCurrentSiteLoader(); - RemoteSiteLoader* GetDefaultRemoteSiteLoader(); - QString GetDefaultRemoteSiteIdent(); - void SetDefaultRemoteSiteIdent(const QString& ident); - QMenu* GetSiteMenu(); - -private: - QMap<QString,RemoteSiteLoader*> site_loaders_; - QActionGroup* site_actions_; - QString default_site_; - - -}; - -typedef boost::shared_ptr<LoaderManager> LoaderManagerPtr; - -} } - -#endif /* OST_GUI_LOADER_MANAGER_HH */ diff --git a/modules/gui/src/remote_loader.cc b/modules/gui/src/remote_loader.cc deleted file mode 100644 index a75a0b4a1..000000000 --- a/modules/gui/src/remote_loader.cc +++ /dev/null @@ -1,208 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the OpenStructure project <www.openstructure.org> -// -// Copyright (C) 2008-2011 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 <vector> - -#include <ost/platform.hh> - -#include <ost/gui/file_loader.hh> -#include <ost/gui/loader_manager.hh> - -#include "widget_registry.hh" -#include "remote_loader.hh" - -#include <QString> -#include <QSettings> -#include <QNetworkReply> -#include <QHBoxLayout> -#include <QDir> -namespace ost { namespace gui { - -RemoteLoader::RemoteLoader(QWidget* parent): - Widget(NULL, parent) -{ - img_support_=OST_IMG_ENABLED; - line_edit_ = new QLineEdit(this); - button_ = new QToolButton(this); - button_->setAttribute(Qt::WA_MacSmallSize); - progress_bar_ = new QProgressBar(this); - progress_bar_->setAttribute(Qt::WA_MacSmallSize); - progress_bar_->setVisible(false); - progress_bar_->setRange(0,0); - - QHBoxLayout* l=new QHBoxLayout(this); - l->addWidget(line_edit_); - l->addWidget(button_); - l->addWidget(progress_bar_); - l->setMargin(3); - l->setSpacing(2); - - connect(button_, SIGNAL(clicked()), this, - SLOT(Clicked())); - - QDir icon_path(GetSharedDataPath().c_str()); - icon_path.cd("gui"); - icon_path.cd("icons"); - site_loader_menu_ = new QMenu(this); - site_actions_ = new QActionGroup(site_loader_menu_); - - site_loader_menu_ = new QMenu(this); - site_actions_ = new QActionGroup(site_loader_menu_); - - QAction* select_url_action = new QAction(this); - select_url_action->setText("URL"); - select_url_action->setToolTip("Select remote URL"); - select_url_action->setIcon(QIcon(icon_path.absolutePath()+QDir::separator()+ - QString("site_icon.png"))); - action_list_.append(select_url_action); - connect(select_url_action, SIGNAL(triggered(bool)), this, SLOT(UrlClick())); - this->BuildMenu(); - this->RenameButton(); - this->setFixedHeight(button_->height()); - this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); -} - -void RemoteLoader::UrlClick() -{ - this->BuildMenu(); - site_loader_menu_->exec(QCursor::pos()); -} - -void RemoteLoader::BuildMenu(String active_loader) -{ - if(!active_loader.empty()){ - selected_site_loader_ = active_loader; - } - else if(site_actions_->checkedAction()!=NULL){ - selected_site_loader_=site_actions_->checkedAction()->text().toStdString(); - } - site_loader_menu_->clear(); - QList<QAction*> actions = site_actions_->actions(); - for(int i=0;i<actions.size();i++){ - site_actions_->removeAction(actions[i]); - } - std::vector<String> site_loaders = FileLoader::GetSiteLoaderIdents(); - for(unsigned int i=0; i<site_loaders.size(); i++){ - QString loader_ident(site_loaders[i].c_str()); - RemoteSiteLoader* loader = FileLoader::GetLoaderManager()->GetRemoteSiteLoader(loader_ident); - if(loader && ((loader->IsImg() && img_support_) || !loader->IsImg())){ - QAction* action = new QAction(loader_ident,site_loader_menu_); - connect(action, SIGNAL(triggered()), this, SLOT(RenameButton())); - action->setCheckable(true); - site_actions_->addAction(action); - if((site_actions_->checkedAction()==NULL && loader_ident == FileLoader::GetLoaderManager()->GetDefaultRemoteSiteIdent()) ||selected_site_loader_==loader_ident.toStdString() ){ - action->setChecked(true); - } - site_loader_menu_->addAction(action); - } - } -} - -ActionList RemoteLoader::GetActions() -{ - return action_list_; -} - -bool RemoteLoader::Save(const QString& prefix) -{ - this->BuildMenu(); - QSettings settings; - settings.beginGroup(prefix); - settings.setValue("loader", site_actions_->checkedAction()->text()); - settings.endGroup(); - return true; -} - -bool RemoteLoader::Restore(const QString& prefix) -{ - QSettings settings; - settings.beginGroup(prefix); - if (settings.contains("loader")) { - this->BuildMenu(settings.value("loader").toString().toStdString()); - } - else{ - this->BuildMenu(); - } - this->RenameButton(); - return true; -} - -void RemoteLoader::Clicked() -{ - this->BuildMenu(); - if(!line_edit_->text().isEmpty() && site_actions_->checkedAction()){ - RemoteSiteLoader* loader = FileLoader::GetLoaderManager()->GetRemoteSiteLoader(site_actions_->checkedAction()->text()); - - QString text = line_edit_->text().simplified(); - QString id = text; - QString selection = ""; - int pos = text.indexOf('['); - if(pos >= 0){ - id = text.left(pos); - selection = text.right(text.size()-(pos+1)); - pos = selection.lastIndexOf(']'); - if(pos>=0){ - selection = selection.left(pos); - } - } - QNetworkReply* network_reply = loader->ById(id,selection); - if(network_reply){ - progress_bar_->reset(); - connect(network_reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(UpdateProgress(qint64,qint64))); - connect(network_reply, SIGNAL(finished()), this, SLOT(DownloadFinished())); - this->ShowProgressBar(true); - } - line_edit_->setText(""); - line_edit_->setFocus(); - } -} - -void RemoteLoader::keyPressEvent(QKeyEvent* event){ - if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { - this->Clicked(); - } -} - -void RemoteLoader::ShowProgressBar(bool visibility){ - button_->setVisible(!visibility); - line_edit_->setVisible(!visibility); - progress_bar_->setVisible(visibility); -} - -void RemoteLoader::UpdateProgress(qint64 read, qint64 total){ - progress_bar_->setMaximum(total); - progress_bar_->setValue(read); - -} - -void RemoteLoader::DownloadFinished(){ - this->ShowProgressBar(false); -} - - -void RemoteLoader::RenameButton(){ - if(site_actions_->checkedAction()){ - QString text = "Load (" + site_actions_->checkedAction()->text() + ")"; - button_->setText(text); - } -} - -OST_REGISTER_WIDGET_WITH_DEFAULT_FACTORY(ost::gui, RemoteLoader, "Remote Loader"); - -}} - diff --git a/modules/io/pymod/CMakeLists.txt b/modules/io/pymod/CMakeLists.txt index 007569fff..6763a0189 100644 --- a/modules/io/pymod/CMakeLists.txt +++ b/modules/io/pymod/CMakeLists.txt @@ -10,7 +10,7 @@ endif() set(OST_IO_PYMOD_MODULES __init__.py - hhsearch.py + remote.py repository.py ) diff --git a/modules/io/pymod/__init__.py b/modules/io/pymod/__init__.py index abe1dcfdb..661d6bbcd 100644 --- a/modules/io/pymod/__init__.py +++ b/modules/io/pymod/__init__.py @@ -60,30 +60,6 @@ def _override(val1, val2): else: return val1 -def __GetModelFromPDB(model_id, output_dir, file_pattern='pdb%s.ent.gz'): - file_name = file_pattern % model_id - file_path = os.path.join(output_dir,file_name) - try: - server="ftp.wwpdb.org" - ftp=ftplib.FTP(server,"anonymous","user@") - ftp.cwd("pub/pdb/data/structures/all/pdb") - ftp_retrfile=open(file_path,"wb") - ftp.retrbinary("RETR "+file_name,ftp_retrfile.write) - ftp_retrfile.close() - except: - conn=httplib.HTTPConnection('www.pdb.org') - conn.request('GET', '/pdb/files/%s.pdb.gz' % model_id ) - response=conn.getresponse() - if response.status==200: - data=response.read() - f=open(os.path.join(output_dir, file_pattern % model_id), 'w+') - f.write(data) - f.close() - else: - conn.close() - return False - return os.path.getsize(file_path) > 0 - def LoadPDB(filename, restrict_chains="", no_hetatms=None, fault_tolerant=None, load_multi=False, quack_mode=None, join_spread_atom_records=None, calpha_only=None, @@ -156,12 +132,11 @@ def LoadPDB(filename, restrict_chains="", no_hetatms=None, prof.join_spread_atom_records=_override(prof.join_spread_atom_records, join_spread_atom_records) + tmp_file = None # avoid getting out of scope if remote: - output_dir = tempfile.gettempdir() - if __GetModelFromPDB(filename, output_dir): - filename = os.path.join(output_dir, 'pdb%s.ent.gz' % filename) - else: - raise IOError('Can not load PDB %s from www.pdb.org'%filename) + from ost.io.remote import RemoteGet + tmp_file =RemoteGet(filename) + filename = tmp_file.name conop_inst=conop.Conopology.Instance() builder=conop_inst.GetBuilder("DEFAULT") diff --git a/modules/io/pymod/remote.py b/modules/io/pymod/remote.py new file mode 100644 index 000000000..102cf6807 --- /dev/null +++ b/modules/io/pymod/remote.py @@ -0,0 +1,93 @@ +#------------------------------------------------------------------------------ +# This file is part of the OpenStructure project <www.openstructure.org> +# +# Copyright (C) 2008-2011 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 +#------------------------------------------------------------------------------ + +import urllib2 +import tempfile + +from ost.io import LoadPDB, LoadMMCIF + +class RemoteRepository: + """ + A remote repository represents a structural database accessible through the + internet, e.g. the PDB or SWISS-MODEL template library. + """ + def __init__(self, name, url_pattern, type, id_transform='upper'): + self.name = name + self.url_pattern = url_pattern + self.type = type + if type not in ('cif', 'pdb'): + raise ValueError('only cif and pdb types are supported') + self.id_transform = id_transform + + def URLForID(self, id): + if self.id_transform == 'upper': + id = id.upper() + if self.id_transform == 'lower': + id = id.lower() + return self.url_pattern.replace('$ID', id) + + def Get(self, id): + remote_url = self.URLForID(id) + tmp_file_suffix = '.%s' % self.type + if remote_url.endswith('.gz'): + tmp_file_suffix+='.gz' + + try: + connection = urllib2.urlopen(remote_url) + status = connection.getcode() + except urllib2.HTTPError, e: + status = e.code + msg = 'Could not load %s from %s (status code %d)' + if status!=200: + raise IOError(msg % (id , self.name ,status)) + tmp_file = tempfile.NamedTemporaryFile(suffix=tmp_file_suffix) + contents = ''.join(connection) + tmp_file.write(contents) + tmp_file.flush() + return tmp_file + + def Load(self, id): + tmp_file = self.Get(id) + if self.type == 'pdb': + return LoadPDB(tmp_file.name) + if self.type == 'cif': + return LoadMMCIF(tmp_file.name) + +REMOTE_REPOSITORIES = { + 'pdb' : RemoteRepository('pdb.org (PDB)', 'http://www.pdb.org/pdb/files/$ID.ent.gz', + type='pdb', id_transform='upper'), + 'smtl' : RemoteRepository('SMTL', 'http://beta.swissmodel.expasy.org/templates/$ID.pdb', + type='pdb', id_transform='lower'), + 'cif' : RemoteRepository('pdb.org (mmCIF)', 'http://www.pdb.org/pdb/files/$ID.cif.gz', + type='cif', id_transform='lower'), + 'pdb_redo' : RemoteRepository('pdbredo', 'http://www.cmbi.ru.nl/pdb_redo/$ID/$ID_besttls.pdb', + type='pdb'), +} + +def RemoteGet(id, from_repo='pdb'): + remote_repo = REMOTE_REPOSITORIES.get(from_repo, None) + if not remote_repo: + raise ValueError('%s is not a valid repository' % from_repo) + return remote_repo.Get(id) + +def RemoteLoad(id ,from_repo='pdb'): + remote_repo = REMOTE_REPOSITORIES.get(from_repo, None) + if not remote_repo: + raise ValueError('%s is not a valid repository' % from_repo) + return remote_repo.Load(id) -- GitLab