def add_project(self): path = self.add_proj_dialog.path.text() description = self.add_proj_dialog.description.toPlainText() if not path: self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage('Path can\'t be empty') return elif not description: self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage('Description can\'t be empty') return data = { "token": self.token, "path": path, "description": description } if self.add_proj_dialog.f_content is not None: data["content"] = self.add_proj_dialog.f_content r = requests.post('{}/create_project'.format(self.mscolab_server_url), data=data) if r.text == "True": self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage('Your project was created successfully') self.add_projects() p_id = self.get_recent_pid() self.conn.handle_new_room(p_id) else: self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage('The path already exists')
def setup_message_box_layout(self): container_layout = QtWidgets.QHBoxLayout() text_area_layout = QtWidgets.QVBoxLayout() if self.chat_window.user["username"] == self.username: text_area_layout.addWidget(self.messageBox) self.textArea.setLayout(text_area_layout) container_layout.addStretch() container_layout.addWidget(self.textArea) else: username_label = QtWidgets.QLabel(f"{self.username}") username_label.setContentsMargins(5, 5, 5, 0) label_font = QtGui.QFont() label_font.setBold(True) username_label.setFont(label_font) text_area_layout.addWidget(username_label) text_area_layout.addWidget(self.messageBox) self.textArea.setLayout(text_area_layout) container_layout.addWidget(self.textArea) container_layout.addStretch() for reply in self.replies: self.add_message_reply(reply) self.textArea.layout().setSpacing(0) self.textArea.layout().setContentsMargins(0, 0, 0, 0) container_layout.setSpacing(0) container_layout.setContentsMargins(5, 5, 5, 5) self.set_message_style() self.setLayout(container_layout)
def add_user(self): for key, value in config_loader(dataset="MSC_login", default={}).items(): if key not in constants.MSC_LOGIN_CACHE: constants.MSC_LOGIN_CACHE[key] = value auth = constants.MSC_LOGIN_CACHE.get(self.mscolab_server_url, (None, None)) emailid = self.add_user_dialog.emailid.text() password = self.add_user_dialog.password.text() re_password = self.add_user_dialog.rePassword.text() username = self.add_user_dialog.username.text() if password == re_password: data = { "email": emailid, "password": password, "username": username } s = requests.Session() s.auth = (auth[0], auth[1]) s.headers.update({'x-test': 'true'}) url = '{}/register'.format(self.mscolab_server_url) r = s.post(url, data=data) if r.status_code == 401: r = self.authenticate(data, r, url) if r.status_code == 201: constants.MSC_LOGIN_CACHE[self.mscolab_server_url] = (username, password) if r.status_code == 201: self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage('You are registered, you can now log in.') else: self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage(r.json()["message"]) else: self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage('Oh no, your passwords don\'t match')
def authorize(self): for key, value in config_loader(dataset="MSC_login", default={}).items(): if key not in constants.MSC_LOGIN_CACHE: constants.MSC_LOGIN_CACHE[key] = value auth = constants.MSC_LOGIN_CACHE.get(self.mscolab_server_url, (None, None)) # get mscolab /token http auth credentials from cache emailid = self.emailid.text() password = self.password.text() data = { "email": emailid, "password": password } s = requests.Session() s.auth = (auth[0], auth[1]) s.headers.update({'x-test': 'true'}) url = self.mscolab_server_url + '/token' r = s.post(url, data=data) if r.status_code == 401: r = self.authenticate(data, r, url) if r.status_code == 200: constants.MSC_LOGIN_CACHE[self.mscolab_server_url] = (auth[0], auth[1]) self.after_authorize(emailid, r) elif r.text == "False": # popup that has wrong credentials self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage('Oh no, your credentials were incorrect.') else: # remove the login modal and put text there self.after_authorize(emailid, r)
def setup(self): self.application = QtWidgets.QApplication(sys.argv) # Create an initital flight track. initial_waypoints = [ ft.Waypoint(flightlevel=0, location="EDMO", comments="take off OP"), ft.Waypoint(48.10, 10.27, 200), ft.Waypoint(52.32, 09.21, 200), ft.Waypoint(52.55, 09.99, 200), ft.Waypoint(flightlevel=0, location="Hamburg", comments="landing HH") ] waypoints_model = ft.WaypointsTableModel("") waypoints_model.insertRows(0, rows=len(initial_waypoints), waypoints=initial_waypoints) self.window = tv.MSSTableViewWindow(model=waypoints_model) self.window.show() QtWidgets.QApplication.processEvents() QtTest.QTest.qWaitForWindowExposed(self.window) QtWidgets.QApplication.processEvents()
def setup(self): # start mscolab server self.app = APP self.app.config[ 'SQLALCHEMY_DATABASE_URI'] = mscolab_settings.SQLALCHEMY_DB_URI self.app.config['MSCOLAB_DATA_DIR'] = mscolab_settings.MSCOLAB_DATA_DIR self.app.config['UPLOAD_FOLDER'] = mscolab_settings.UPLOAD_FOLDER self.app, _, cm, fm = initialize_managers(self.app) self.fm = fm self.cm = cm db.init_app(self.app) logging.debug("starting") self.application = QtWidgets.QApplication(sys.argv) self.window = MSSMscolabWindow( data_dir=mscolab_settings.MSCOLAB_DATA_DIR, mscolab_server_url=MSCOLAB_URL_TEST) self._login() self._activate_project_at_index(0) # activate project window here by clicking button QtTest.QTest.mouseClick(self.window.chatWindowBtn, QtCore.Qt.LeftButton) QtWidgets.QApplication.processEvents() self.chat_window = self.window.chat_window QtTest.QTest.qWaitForWindowExposed(self.window) QtWidgets.QApplication.processEvents()
def createEditor(self, parent, option, index): """Create a combobox listing predefined locations in the LOCATION column. """ if index.column() == LOCATION: combobox = QtWidgets.QComboBox(parent) locations = config_loader(dataset='locations', default=mss_default.locations) adds = list(locations.keys()) if self.parent() is not None: for loc in [ wp.location for wp in self.parent().waypoints_model.all_waypoint_data() if wp.location != "" ]: if loc not in adds: adds.append(loc) combobox.addItems(sorted(adds)) combobox.setEditable(True) return combobox else: # All other columns get the standard editor. return QtWidgets.QItemDelegate.createEditor( self, parent, option, index)
def add_export_filter(self, name, extension, function, pickertag=None, pickertype=None): full_name = "actionExportFlightTrack" + clean_string(name) if hasattr(self, full_name): raise ValueError("'{}' has already been set!".format(full_name)) action = QtWidgets.QAction(self) action.setObjectName(full_name) action.setText(QtCore.QCoreApplication.translate("MSSMainWindow", name, None)) self.menuExport_Active_Flight_Track.addAction(action) def save_function_wrapper(self): default_filename = os.path.join(self.last_save_directory, self.active_flight_track.name) + "." + extension filename = get_save_filename( self, "Export Flight Track", default_filename, name + " (*." + extension + ")", pickertype=pickertype) if filename is not None: try: function(filename, self.active_flight_track.name, self.active_flight_track.waypoints) # wildcard exception to be resilient against error introduced by user code except Exception as ex: logging.error("file io plugin error: %s %s", type(ex), ex) QtWidgets.QMessageBox.critical( self, self.tr("file io plugin error"), self.tr("ERROR: {} {}".format(type(ex), ex))) setattr(self, full_name, types.MethodType(save_function_wrapper, self)) action.triggered.connect(getattr(self, full_name))
def populate_table(self, table, users): table.setRowCount(0) for row_number, row_data in enumerate(users): table.insertRow(row_number) for col_number, item in enumerate(row_data): new_item = QtWidgets.QTableWidgetItem(item) table.setItem(row_number, col_number, new_item)
def setup(self): self.application = QtWidgets.QApplication(sys.argv) self.window = tv.MSS_TV_MapAppearanceDialog() self.window.show() QtWidgets.QApplication.processEvents() QtTest.QTest.qWaitForWindowExposed(self.window) QtWidgets.QApplication.processEvents()
def setup(self): self.application = QtWidgets.QApplication(sys.argv) self.tempdir = tempfile.mkdtemp() if not os.path.exists(self.tempdir): os.mkdir(self.tempdir) self.thread = multiprocessing.Process(target=application.run, args=("127.0.0.1", 8082)) self.thread.start() initial_waypoints = [ ft.Waypoint(40., 25., 0), ft.Waypoint(60., -10., 0), ft.Waypoint(40., 10, 0) ] waypoints_model = ft.WaypointsTableModel("") waypoints_model.insertRows(0, rows=len(initial_waypoints), waypoints=initial_waypoints) self.window = tv.MSSTopViewWindow(model=waypoints_model) self.window.show() QtWidgets.QApplication.processEvents() QtTest.QTest.qWait(2000) QtTest.QTest.qWaitForWindowExposed(self.window) QtWidgets.QApplication.processEvents() self.window.cbTools.currentIndexChanged.emit(1) QtWidgets.QApplication.processEvents() self.wms_control = self.window.docks[0].widget() self.wms_control.cbWMS_URL.setEditText("")
def load_all_changes(self): """ get changes from api, clear listwidget, render them to ui """ data = {"token": self.token, "p_id": self.p_id} named_version_only = None if self.versionFilterCB.currentIndex() == 0: named_version_only = True query_string = url_encode({"named_version": named_version_only}) url_path = f'get_all_changes?{query_string}' url = url_join(self.mscolab_server_url, url_path) r = requests.get(url, data=data) changes = json.loads(r.text)["changes"] self.changes.clear() for change in changes: created_at = datetime.strptime(change["created_at"], "%Y-%m-%d, %H:%M:%S") local_time = utc_to_local_datetime(created_at) date = local_time.strftime('%d/%m/%Y') time = local_time.strftime('%I:%M %p') item_text = f'{change["username"]} made change on {date} at {time}' if change["version_name"] is not None: item_text = f'{change["version_name"]}\n{item_text}' item = QtWidgets.QListWidgetItem(item_text, parent=self.changes) item.id = change["id"] item.version_name = change["version_name"] self.changes.addItem(item)
def preload_wms(urls): """ This method accesses a list of WMS servers and load their capability documents. :param urls: List of URLs """ pdlg = QtWidgets.QProgressDialog("Preloading WMS servers...", "Cancel", 0, len(urls)) pdlg.reset() pdlg.setValue(0) pdlg.setModal(True) pdlg.show() QtWidgets.QApplication.processEvents() for i, base_url in enumerate(urls): pdlg.setValue(i) QtWidgets.QApplication.processEvents() # initialize login cache from config file, but do not overwrite existing keys for key, value in config_loader(dataset="WMS_login", default={}).items(): if key not in constants.WMS_LOGIN_CACHE: constants.WMS_LOGIN_CACHE[key] = value username, password = constants.WMS_LOGIN_CACHE.get(base_url, (None, None)) try: request = requests.get(base_url) if pdlg.wasCanceled(): break wms = wms_control.MSSWebMapService(request.url, version='1.1.1', username=username, password=password) wms_control.WMS_SERVICE_CACHE[wms.url] = wms logging.info("Stored WMS info for '%s'", wms.url) except Exception as ex: logging.error("Error in preloading '%s': '%s'", type(ex), ex) if pdlg.wasCanceled(): break logging.debug("Contents of WMS_SERVICE_CACHE: %s", wms_control.WMS_SERVICE_CACHE.keys()) pdlg.close()
def create_list_item(self, text): """ PyQt5 method : Add items in list and add checkbox functionality """ item = QtWidgets.QListWidgetItem(text) item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) item.setCheckState(QtCore.Qt.Checked) self.listWidget.addItem(item)
def add_project_handler(self): if self.token is None: self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage('Please login to use this feature') return else: logging.debug(self.token) self.proj_diag = QtWidgets.QDialog() self.add_proj_dialog = add_project_ui.Ui_addProjectDialog() self.add_proj_dialog.setupUi(self.proj_diag) self.add_proj_dialog.f_content = None self.add_proj_dialog.buttonBox.accepted.connect(self.add_project) self.add_proj_dialog.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(False) self.add_proj_dialog.path.textChanged.connect(self.check_and_enable_project_accept) self.add_proj_dialog.description.textChanged.connect(self.check_and_enable_project_accept) self.add_proj_dialog.browse.clicked.connect(self.set_exported_file) self.proj_diag.show()
def setup(self): self.application = QtWidgets.QApplication(sys.argv) self.view = mock.Mock() self.window = sd.SatelliteControlWidget(view=self.view) self.window.show() QtWidgets.QApplication.processEvents() QtTest.QTest.qWaitForWindowExposed(self.window) QtWidgets.QApplication.processEvents()
def render_new_message(self, message, scroll=True): message_item = MessageItem(message, self) list_widget_item = QtWidgets.QListWidgetItem(self.messageList) list_widget_item.setSizeHint(message_item.sizeHint()) self.messageList.addItem(list_widget_item) self.messageList.setItemWidget(list_widget_item, message_item) if scroll: self.messageList.scrollToBottom()
def setup(self): self.application = QtWidgets.QApplication(sys.argv) self.window = mss_pyui.MSSMainWindow() self.window.create_new_flight_track() self.window.show() QtWidgets.QApplication.processEvents() QtTest.QTest.qWaitForWindowExposed(self.window) QtWidgets.QApplication.processEvents()
def add_message_reply(self, reply): if self.replyArea is None: self.insert_reply_area() reply_username_label = QtWidgets.QLabel(f'{reply["username"]}:') label_font = QtGui.QFont() label_font.setBold(True) reply_username_label.setFont(label_font) reply_message_box = self.get_text_browser(reply["text"]) self.replyArea.layout().addRow(reply_username_label, reply_message_box)
def insert_reply_area(self): self.replyArea = QtWidgets.QGroupBox() reply_area_layout = QtWidgets.QFormLayout() reply_area_layout.setSpacing(0) reply_area_layout.setContentsMargins(5, 0, 0, 0) self.replyArea.setLayout(reply_area_layout) self.replyScroll.setHorizontalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff) self.replyScroll.setVerticalScrollBarPolicy( QtCore.Qt.ScrollBarAsNeeded) self.replyScroll.setMaximumHeight(150) self.replyScroll.setWidgetResizable(True) self.replyScroll.setWidget(self.replyArea) self.replyScroll.setContentsMargins(0, 0, 0, 0) self.textArea.layout().addWidget(self.replyScroll) if self.username == self.chat_window.user["username"]: color = "#c3f39e" else: color = "#e2e3e5" self.messageBox.setStyleSheet( "background: transparent; border-bottom: 1px solid black;") self.replyScroll.setStyleSheet(f"background: {color}")
def delete_account(self): w = QtWidgets.QWidget() qm = QtWidgets.QMessageBox reply = qm.question(w, self.tr('Continue?'), self.tr("You're about to delete your account. You cannot undo this operation!"), qm.Yes, qm.No) if reply == QtWidgets.QMessageBox.No: return data = { "token": self.token } requests.post(self.mscolab_server_url + '/delete_user', data=data) self.clean_up_window()
def setup(self): self.application = QtWidgets.QApplication(sys.argv) self.view = mock.Mock() self.view.map = mock.Mock(side_effect=lambda x, y: (x, y)) self.view.map.plot = mock.Mock(return_value=[mock.Mock()]) self.window = kd.KMLOverlayControlWidget(view=self.view) self.window.show() QtWidgets.QApplication.processEvents() QtTest.QTest.qWaitForWindowExposed(self.window) # start load test self.window.select_all() self.window.remove_file() QtWidgets.QApplication.processEvents()
def setup(self): self.application = QtWidgets.QApplication(sys.argv) self.capabilities = mock.Mock() self.capabilities.capabilities_document = u"Hölla die Waldfee".encode( "utf-8") self.capabilities.provider = mock.Mock() self.capabilities.identification = mock.Mock() self.capabilities.provider.contact = mock.Mock() self.capabilities.provider.contact.name = None self.capabilities.provider.contact.organization = None self.capabilities.provider.contact.email = None self.capabilities.provider.contact.address = None self.capabilities.provider.contact.postcode = None self.capabilities.provider.contact.city = None
def get_text_browser(self, text): text_browser = QtWidgets.QTextBrowser() html = self.chat_window.markdown.convert(text) text_browser.setHtml(html) text_browser.setOpenLinks(False) text_browser.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) text_browser.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) text_browser.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) text_browser.setAttribute(103) text_browser.anchorClicked.connect(self.on_link_click) text_browser.show() text_browser.setFixedHeight(text_browser.document().size().height() + text_browser.contentsMargins().top() * 2) return text_browser
def __init__(self, message, chat_window): super(MessageItem, self).__init__() self.id = message["id"] self.u_id = message["u_id"] self.username = message["username"] self.message_type = message["message_type"] self.replies = message["replies"] self.time = message["time"] self.chat_window = chat_window self.message_text = None self.attachment_path = None self.message_image = None self.messageBox = None if self.message_type in (MessageType.TEXT, MessageType.SYSTEM_MESSAGE): self.message_text = message["text"] else: self.attachment_path = message["text"] self.context_menu = QtWidgets.QMenu(self) self.textArea = QtWidgets.QWidget() self.replyArea = None self.replyScroll = QtWidgets.QScrollArea() self.setup_message_box() self.setup_message_box_layout() self.setup_context_menu()
def __init__(self, parent=None): # initialization of Qt MainWindow widget super(MplWidget, self).__init__(parent) # set the canvas to the Matplotlib widget self.canvas = MplCanvas() # create a vertical box layout self.vbl = QtWidgets.QVBoxLayout() # add mpl widget to vertical box self.vbl.addWidget(self.canvas) # set the layout to th vertical box self.setLayout(self.vbl)
def add_projects_to_ui(self, projects): logging.debug("adding projects to ui") self.listProjects.clear() selectedProject = None for project in projects: project_desc = f'{project["path"]} - {project["access_level"]}' widgetItem = QtWidgets.QListWidgetItem(project_desc, parent=self.listProjects) widgetItem.p_id = project["p_id"] widgetItem.access_level = project["access_level"] if widgetItem.p_id == self.active_pid: selectedProject = widgetItem self.listProjects.addItem(widgetItem) if selectedProject is not None: self.listProjects.setCurrentItem(selectedProject) self.listProjects.itemActivated.emit(selectedProject) self.listProjects.itemActivated.connect(self.set_active_pid)
def setup(self): self.application = QtWidgets.QApplication(sys.argv) initial_waypoints = [ ft.Waypoint(40., 25., 0), ft.Waypoint(60., -10., 0), ft.Waypoint(40., 10, 0) ] waypoints_model = ft.WaypointsTableModel("") waypoints_model.insertRows(0, rows=len(initial_waypoints), waypoints=initial_waypoints) self.window = tv.MSSTopViewWindow(model=waypoints_model) self.window.show() QtWidgets.QApplication.processEvents() QtTest.QTest.qWaitForWindowExposed(self.window) QtWidgets.QApplication.processEvents()
def setup_image_message_box(self): MAX_WIDTH = MAX_HEIGHT = 300 self.messageBox = QtWidgets.QLabel() img_url = url_join(self.chat_window.mscolab_server_url, self.attachment_path) data = requests.get(img_url).content image = QtGui.QImage() image.loadFromData(data) self.message_image = image width, height = image.size().width(), image.size().height() if width > height and width > MAX_WIDTH: image = image.scaledToWidth(MAX_WIDTH) elif height > width and height > MAX_HEIGHT: image = image.scaledToHeight(MAX_HEIGHT) self.messageBox.setPixmap(QtGui.QPixmap(image)) self.messageBox.setContentsMargins(0, 5, 0, 5) self.messageBox.show()
def load_users(self): # load users to side-tab here # make request to get users data = {"token": self.token, "p_id": self.p_id} url = url_join(self.mscolab_server_url, 'authorized_users') r = requests.get(url, data=data) if r.text == "False": show_popup(self, "Error", "Some error occurred while fetching users!") else: self.collaboratorsList.clear() users = r.json()["users"] for user in users: item = QtWidgets.QListWidgetItem( f'{user["username"]} - {user["access_level"]}', parent=self.collaboratorsList) self.collaboratorsList.addItem(item)