def start_web(self): project_label = "{} {}".format(strings._("open_project", True), self.project.folder) self.logs_layout.reset_lektor_log_container(project_label) self.web = Web(self.base, self.project, False, self.logs_layout.lektor_log_container) self.web.start() self.logs_layout.append_lektor_log_container("{} {}:{}".format( strings._("serve_project", True), self.web.address, self.web.port))
def __init__(self, base, layout, main_window): self.base = base self.layout = layout self.main_window = main_window self.log_layout = QtWidgets.QHBoxLayout() self.log_layout.setSpacing(0) self.log_layout.setContentsMargins(0, 0, 0, 0) self.tab_layout = QtWidgets.QHBoxLayout() self.tab_layout.setSpacing(0) self.tab_layout.setContentsMargins(0, 0, 0, 0) # Define log boxes self.lektor_log_container = QPlainTextEditLogger( main_window, self.base) self.onion_log_container = QPlainTextEditLogger(main_window, self.base) self.git_log_container = QPlainTextEditLogger(main_window, self.base) self.lektor_log_container.widget.show() self.onion_log_container.widget.hide() self.git_log_container.widget.hide() # Define tab buttons self.lektor_log_button = QtWidgets.QPushButton( strings._('tab_web', True)) self.lektor_log_button.setFixedHeight(20) self.lektor_log_button.setStyleSheet(self.base.css["tab_button"]) self.lektor_log_button.clicked.connect( main_window.lektor_log_button_clicked) self.git_log_button = QtWidgets.QPushButton(strings._('tab_git', True)) self.git_log_button.setFixedHeight(20) self.git_log_button.setStyleSheet(self.base.css["tab_button"]) self.git_log_button.clicked.connect(main_window.git_log_button_clicked) self.onion_log_button = QtWidgets.QPushButton( strings._('tab_onion', True)) self.onion_log_button.setFixedHeight(20) self.onion_log_button.setStyleSheet(self.base.css["tab_button"]) self.onion_log_button.clicked.connect( main_window.onion_log_button_clicked) # Add log container to panel self.log_layout.addWidget(self.lektor_log_container.widget) self.log_layout.addWidget(self.onion_log_container.widget) self.log_layout.addWidget(self.git_log_container.widget) # Add tab layout to panel self.tab_layout.addWidget(self.lektor_log_button) self.tab_layout.addWidget(self.git_log_button) self.tab_layout.addWidget(self.onion_log_button) # Add panels to layout self.layout.addLayout(self.log_layout) self.layout.addLayout(self.tab_layout)
def __init__(self, base, layout, main_window): self.base = base self.layout = layout self.main_window = main_window self.project_layout = QtWidgets.QHBoxLayout() self.project_layout.setSpacing(0) self.project_layout.setContentsMargins(0, 0, 0, 0) # Define project status box self.project_status_label = QtWidgets.QLabel("{}: ".format( strings._('project_status_label', True))) self.project_status_label.setFixedHeight(50) self.project_status_label.setStyleSheet( self.base.css["project_status_indicator_label"]) # Add project status to panel self.project_layout.addWidget(self.project_status_label) self.layout.addLayout(self.project_layout) project_folder = self.base.settings.get("project_folder") if project_folder: self.set_project_label(project_folder) self.main_window.set_project(project_folder) self.main_window.start_web()
def save_clicked(self): self.base.log('[GhostWriterGui][SettingsPanel]', 'Save settings') def changed(s1, s2, keys): """ Compare the Settings objects s1 and s2 and return true if any values have changed for the given keys. """ for key in keys: if s1.get(key) != s2.get(key): return True return False settings = self.settings_from_panel() if settings: # If language changed, inform user they need to restart OnionShare if changed(settings, self.old_settings, ["locale"]): # Look up error message in different locale new_locale = settings.get("locale") if (new_locale in strings.translations and "settings_language_changed_notice" in strings.translations[new_locale]): notice = strings.translations[new_locale][ "settings_language_changed_notice"] else: notice = strings._("settings_language_changed_notice") Alert(self.base, notice, QtWidgets.QMessageBox.Information) # Save the new settings settings.save() self.settings_saved.emit() self.close()
def main(): """ The main() function implements all of the logic that the GUI version of ghostwriter uses. """ base = Base() base.define_css() config = False strings.load_strings(base) print(strings._('version_string').format(base.version)) # Allow Ctrl-C to smoothly quit the program instead of throwing an exception # https://stackoverflow.com/questions/42814093/how-to-handle-ctrlc-in-python-app-with-pyqt signal.signal(signal.SIGINT, signal.SIG_DFL) # Start the Qt app global qtapp qtapp = Application(base) # Launch the gui gui = GhostWriterGui(base, qtapp, config) # Clean up when app quits def shutdown(): print("Shutting down") gui.stop() qtapp.aboutToQuit.connect(shutdown) # All done sys.exit(qtapp.exec_())
def __init__(self, base, project, parent, config=False): self.base = base self.project = project self.parent = parent self.config = config self.current_settings = Settings(self.base, self.config) self.current_settings.load() project_folder = QtWidgets.QFileDialog.getExistingDirectory( self.parent, caption=strings._("gui_choose_folder"), options=QtWidgets.QFileDialog.ShowDirsOnly, ) self.project.set_folder(project_folder) project_status = "{}: {}".format( strings._("project_status_label", True), self.project.folder) self.parent.project_layout.set_project_label(project_status) if (self.current_settings.get("project_folder") != project_folder): settings = Settings(self.base, self.config) settings.set("project_folder", project_folder) settings.save() self.current_settings.load() try: repo = git.Repo(self.project.folder) except Exception as e: parent.logs_layout.append_git_log_container(e) self.current_settings.set("git_repository", repo.remotes.origin.url) self.project.set_master = repo.remotes.origin.url self.current_settings.set("upstream_git_repository", repo.remotes.upstream.url) self.project.set_upstream = repo.remotes.upstream.url self.current_settings.save()
def onion_button_clicked(self): self.base.log('[GhostWriterGui]', 'Onion button clicked') self.logs_layout.show_onion_log_container() if (self.base.settings.get("onion_share_method") == "docker"): self.logs_layout.reset_onion_log_container("{}: {}".format( strings._("onion_starting", True), self.project.folder)) self.container_path = self.base.get_resource_path( 'containers/website') self.onion = DockerOnion(self.base, self.project, self.container_path, False, self.logs_layout.onion_log_container) self.onion.start() else: self.onion = OnionShare(self.base, self.project, False, self.logs_layout.onion_log_container) self.onion.start()
def __init__(self, base, qtapp, config=False): super(GhostWriterGui, self).__init__() self.qtapp = qtapp self.base = base self.base.log("[GhostWriterGui]", "__init__") # Load settings, if a custom config was passed in self.config = config if self.config: self.base.load_settings(self.config) else: self.base.load_settings() self.setMinimumWidth(820) self.setMinimumHeight(660) self.setWindowTitle("GhostWriter") self.setWindowIcon( QtGui.QIcon(self.base.get_resource_path("images/ghostwriter.png"))) # System tray menu = QtWidgets.QMenu() self.settings_action = menu.addAction( strings._('gui_settings_window_title', True)) self.settings_action.triggered.connect(self.open_settings) exit_action = menu.addAction(strings._('systray_menu_exit', True)) exit_action.triggered.connect(self.close) self.system_tray = QtWidgets.QSystemTrayIcon(self) # The convention is Mac systray icons are always grayscale if self.base.platform == 'Darwin': self.system_tray.setIcon( QtGui.QIcon( self.base.get_resource_path( 'images/ghostwriter-grayscale.png'))) else: self.system_tray.setIcon( QtGui.QIcon( self.base.get_resource_path('images/ghostwriter.png'))) self.system_tray.setContextMenu(menu) self.system_tray.show() # Create layout self.layout = QtWidgets.QVBoxLayout() self.layout.setSpacing(0) self.layout.setContentsMargins(0, 0, 0, 0) self.menu_layout = MenuLayout(self.base, self.layout, self) self.logs_layout = LogsLayout(self.base, self.layout, self) self.project_layout = ProjectLayout(self.base, self.layout, self) # Create widget central_widget = QtWidgets.QWidget() # Add layout central_widget.setLayout(self.layout) central_widget.setContentsMargins(0, 0, 0, 0) self.setCentralWidget(central_widget) self.show()
def __init__(self, base, layout, main_window): self.base = base self.layout = layout self.main_window = main_window # Define menu buttons and labels self.open_label = QtWidgets.QLabel(strings._('button_open', True)) self.open_label.setStyleSheet(self.base.css["menu_label"]) self.open_label.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) self.open_label.setFixedHeight(50) self.open_button = QtWidgets.QPushButton() self.open_button.setFixedHeight(50) self.open_button.setIcon( QtGui.QIcon( self.base.get_resource_path("images/icons/folder-3x.png"))) self.open_button.setStyleSheet(self.base.css["menu_button"]) self.open_button.clicked.connect(main_window.open_button_clicked) self.close_label = QtWidgets.QLabel(strings._('button_close', True)) self.close_label.setStyleSheet(self.base.css["menu_label"]) self.close_label.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) self.close_label.setFixedHeight(50) self.close_button = QtWidgets.QPushButton() self.close_button.setFixedHeight(50) self.close_button.setIcon( QtGui.QIcon(self.base.get_resource_path("images/icons/x-3x.png"))) self.close_button.setStyleSheet(self.base.css["menu_button"]) self.close_button.clicked.connect(main_window.close_button_clicked) self.view_label = QtWidgets.QLabel(strings._('button_view', True)) self.view_label.setStyleSheet(self.base.css["menu_label"]) self.view_label.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) self.view_label.setFixedHeight(50) self.view_button = QtWidgets.QPushButton() self.view_button.setFixedHeight(50) self.view_button.setIcon( QtGui.QIcon( self.base.get_resource_path("images/icons/eye-3x.png"))) self.view_button.setStyleSheet(self.base.css["menu_button"]) self.view_button.clicked.connect(main_window.view_button_clicked) self.edit_label = QtWidgets.QLabel(strings._('button_edit', True)) self.edit_label.setStyleSheet(self.base.css["menu_label"]) self.edit_label.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) self.edit_label.setFixedHeight(50) self.edit_button = QtWidgets.QPushButton() self.edit_button.setFixedHeight(50) self.edit_button.setIcon( QtGui.QIcon( self.base.get_resource_path("images/icons/pencil-3x.png"))) self.edit_button.setStyleSheet(self.base.css["menu_button"]) self.edit_button.clicked.connect(main_window.edit_button_clicked) self.push_label = QtWidgets.QLabel(strings._('button_push', True)) self.push_label.setStyleSheet(self.base.css["menu_label"]) self.push_label.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) self.push_button = QtWidgets.QPushButton() self.push_button.setFixedHeight(50) self.push_button.setIcon( QtGui.QIcon( self.base.get_resource_path( "images/icons/data-transfer-upload-3x.png"))) self.push_button.setStyleSheet(self.base.css["menu_button"]) self.push_button.clicked.connect(main_window.push_button_clicked) self.sync_label = QtWidgets.QLabel(strings._('button_sync', True)) self.sync_label.setStyleSheet(self.base.css["menu_label"]) self.sync_label.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) self.sync_label.setFixedHeight(50) self.sync_button = QtWidgets.QPushButton() self.sync_button.setFixedHeight(50) self.sync_button.setIcon( QtGui.QIcon( self.base.get_resource_path("images/icons/reload-3x.png"))) self.sync_button.setStyleSheet(self.base.css["menu_button"]) self.sync_button.clicked.connect(main_window.sync_button_clicked) self.rebase_label = QtWidgets.QLabel(strings._('button_rebase', True)) self.rebase_label.setStyleSheet(self.base.css["menu_label"]) self.rebase_label.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) self.rebase_label.setFixedHeight(50) self.rebase_button = QtWidgets.QPushButton() self.rebase_button.setFixedHeight(50) self.rebase_button.setIcon( QtGui.QIcon( self.base.get_resource_path("images/icons/fork-3x.png"))) self.rebase_button.setStyleSheet(self.base.css["menu_button"]) self.rebase_button.clicked.connect(main_window.rebase_button_clicked) self.onion_label = QtWidgets.QLabel(strings._('button_onion', True)) self.onion_label.setStyleSheet(self.base.css["menu_label"]) self.onion_label.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) self.onion_label.setFixedHeight(50) self.onion_button = QtWidgets.QPushButton() self.onion_button.setFixedHeight(50) self.onion_button.setIcon( QtGui.QIcon( self.base.get_resource_path("images/icons/shield-3x.png"))) self.onion_button.setStyleSheet(self.base.css["menu_button"]) self.onion_button.clicked.connect(main_window.onion_button_clicked) self.settings_label = QtWidgets.QLabel( strings._('button_settings', True)) self.settings_label.setStyleSheet(self.base.css["menu_label"]) self.settings_label.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) self.settings_label.setFixedHeight(50) self.settings_button = QtWidgets.QPushButton() self.settings_button.setFixedHeight(50) self.settings_button.setIcon( QtGui.QIcon( self.base.get_resource_path("images/icons/cog-3x.png"))) self.settings_button.setStyleSheet(self.base.css["menu_button"]) self.settings_button.clicked.connect( main_window.settings_button_clicked) # Define menu panel self.labels_layout = QtWidgets.QHBoxLayout() self.labels_layout.setSpacing(0) self.labels_layout.setContentsMargins(0, 0, 0, 0) self.panel_layout = QtWidgets.QHBoxLayout() self.panel_layout.setSpacing(0) self.panel_layout.setContentsMargins(0, 0, 0, 0) # Add labels to panel self.labels_layout.addWidget(self.open_label) self.labels_layout.addWidget(self.close_label) self.labels_layout.addWidget(self.view_label) self.labels_layout.addWidget(self.edit_label) self.labels_layout.addWidget(self.push_label) self.labels_layout.addWidget(self.sync_label) self.labels_layout.addWidget(self.rebase_label) self.labels_layout.addWidget(self.onion_label) self.labels_layout.addWidget(self.settings_label) # Add buttons to panel self.panel_layout.addWidget(self.open_button) self.panel_layout.addWidget(self.close_button) self.panel_layout.addWidget(self.view_button) self.panel_layout.addWidget(self.edit_button) self.panel_layout.addWidget(self.push_button) self.panel_layout.addWidget(self.sync_button) self.panel_layout.addWidget(self.rebase_button) self.panel_layout.addWidget(self.onion_button) self.panel_layout.addWidget(self.settings_button) self.layout.addLayout(self.labels_layout) self.layout.addLayout(self.panel_layout)
def __init__(self, base, qtapp, layout, config=False): super(SettingsPanel, self).__init__() self.base = base self.qtapp = qtapp self.layout = layout self.config = config self.old_settings = Settings(self.base, self.config) self.old_settings.load() self.base.log('[GhostWriterGui][SettingsPanel]', '__init__') self.setModal(True) self.setWindowTitle(strings._("gui_settings_window_title")) self.setWindowIcon( QtGui.QIcon(self.base.get_resource_path("images/ghostwriter.png"))) self.system = platform.system() self.top_label = QtWidgets.QLabel() self.top_label.setPixmap( QtGui.QPixmap( self.base.get_resource_path("images/ghostwriter.png"))) self.top_layout = QtWidgets.QHBoxLayout() self.top_layout.addWidget(self.top_label) self.upstream_git_repository_label = QtWidgets.QLabel( strings._('upstream_git_repository_label', True)) self.upstream_git_repository_label.setStyleSheet( self.base.css["settings_label"]) self.upstream_git_repository_label.setAlignment( QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) self.upstream_git_repository_field = QtWidgets.QLineEdit( self.old_settings.get("upstream_git_repository")) self.upstream_git_layout = QtWidgets.QHBoxLayout() self.upstream_git_layout.setSpacing(0) self.upstream_git_layout.setContentsMargins(0, 0, 0, 0) self.upstream_git_layout.addWidget(self.upstream_git_repository_label) self.upstream_git_layout.addWidget(self.upstream_git_repository_field) self.git_repository_label = QtWidgets.QLabel( strings._('git_repository_label', True)) self.git_repository_label.setStyleSheet( self.base.css["settings_label"]) self.git_repository_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) self.git_repository_field = QtWidgets.QLineEdit( self.old_settings.get("git_repository")) self.git_layout = QtWidgets.QHBoxLayout() self.git_layout.addWidget(self.git_repository_label) self.git_layout.addWidget(self.git_repository_field) self.onion_method_label = QtWidgets.QLabel( strings._('onion_method_label', True)) self.onion_method_label.setStyleSheet(self.base.css["settings_label"]) self.onion_method_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) self.onion_radio_button = QtWidgets.QRadioButton("OnionShare") self.onion_radio_button.share = "OnionShare" self.onion_radio_button.toggled.connect(self.radio_clicked) self.docker_radio_button = QtWidgets.QRadioButton("Docker Container") self.docker_radio_button.share = "Docker" self.docker_radio_button.toggled.connect(self.radio_clicked) if self.old_settings.get("onion_share_method") == "docker": self.docker_radio_button.setChecked(True) else: self.onion_radio_button.setChecked(True) self.radio_layout = QtWidgets.QHBoxLayout() self.radio_layout.addWidget(self.onion_method_label) self.radio_layout.addWidget(self.onion_radio_button) self.radio_layout.addWidget(self.docker_radio_button) self.save_button = QtWidgets.QPushButton( strings._('save_button_label', True)) self.save_button.setFixedHeight(50) self.save_button.setStyleSheet(self.base.css["settings_button"]) self.save_button.clicked.connect(self.save_clicked) self.cancel_button = QtWidgets.QPushButton( strings._('cancel_button_label', True)) self.cancel_button.setFixedHeight(50) self.cancel_button.setStyleSheet(self.base.css["settings_button"]) self.cancel_button.clicked.connect(self.cancel_clicked) self.buttons_layout = QtWidgets.QHBoxLayout() self.buttons_layout.addWidget(self.save_button) self.buttons_layout.addWidget(self.cancel_button) settings_layout = QtWidgets.QVBoxLayout() settings_layout.addLayout(self.top_layout) settings_layout.addLayout(self.upstream_git_layout) settings_layout.addLayout(self.git_layout) settings_layout.addLayout(self.radio_layout) settings_layout.addLayout(self.buttons_layout) self.setLayout(settings_layout)