Beispiel #1
0
 def on_right_click(self, position):
     item = self.model().itemFromIndex(self.indexAt(position))
     if item:
         folder = self.model().item(item.row(), 0).text()
         folder_info = self.gateway.magic_folders.get(folder)
         menu = QMenu()
         remove_action = QAction(QIcon(resource('close.png')),
                                 "Remove {}".format(folder), menu)
         remove_action.triggered.connect(
             lambda: self.confirm_remove(folder))
         share_action = QAction(QIcon(resource('share.png')), "Share...")
         share_action.triggered.connect(
             lambda: self.open_share_widget(folder))
         if folder_info:
             open_action = QAction("Open")
             open_action.triggered.connect(
                 lambda: open_folder(folder_info['directory']))
             menu.addAction(open_action)
         else:
             download_action = QAction(QIcon(resource('download.png')),
                                       'Download...', self)
             download_action.setStatusTip('Download...')
             download_action.triggered.connect(
                 lambda: self.select_download_location(folder))
             menu.addAction(download_action)
             share_action.setEnabled(False)
         menu.addAction(share_action)
         menu.addSeparator()
         menu.addAction(remove_action)
         menu.exec_(self.viewport().mapToGlobal(position))
Beispiel #2
0
    def __init__(self, parent=None):
        super(InviteCodeLineEdit, self).__init__()
        self.parent = parent
        model = QStringListModel()
        model.setStringList(wordlist)
        completer = InviteCodeCompleter()
        completer.setModel(model)
        self.setFont(Font(16))
        self.setCompleter(completer)
        self.setAlignment(Qt.AlignCenter)
        # self.setPlaceholderText("Enter invite code")

        self.blank_icon = QIcon()
        self.paste_icon = QIcon(resource("paste.png"))
        self.clear_icon = QIcon(resource("close.png"))
        self.go_icon = QIcon(resource("arrow-right.png"))
        self.tor_icon = QIcon(resource("tor-onion.png"))

        self.status_action = QAction(self.blank_icon, "", self)
        self.addAction(self.status_action, 0)
        self.action_button = QAction(self.blank_icon, "", self)
        self.addAction(self.action_button, 1)

        completer.highlighted.connect(self.update_action_button)
        self.textChanged.connect(self.update_action_button)
        self.returnPressed.connect(self.return_pressed)
        self.action_button.triggered.connect(self.button_clicked)

        self.update_action_button()
Beispiel #3
0
    def on_right_click(self, position):
        if not position:
            position = self.viewport().mapFromGlobal(QCursor().pos())
        cur_item = self.model().itemFromIndex(self.indexAt(position))
        if not cur_item:
            return
        cur_folder = self.model().item(cur_item.row(), 0).text()

        if self.gateway.magic_folders.get(cur_folder):  # is local folder
            selection_is_remote = False
            self.deselect_remote_folders()
        else:
            selection_is_remote = True
            self.deselect_local_folders()

        selected = self.get_selected_folders()
        if not selected:
            selected = [cur_folder]

        menu = QMenu()
        if selection_is_remote:
            download_action = QAction(QIcon(resource('download.png')),
                                      "Download...")
            download_action.triggered.connect(
                lambda: self.select_download_location(selected))
            menu.addAction(download_action)
            menu.addSeparator()
        open_action = QAction(self.model().icon_folder_gray, "Open")
        open_action.triggered.connect(lambda: self.open_folders(selected))

        share_menu = QMenu()
        share_menu.setIcon(QIcon(resource('laptop.png')))
        share_menu.setTitle("Sync with device")  # XXX Rephrase?
        invite_action = QAction(QIcon(resource('invite.png')),
                                "Create Invite Code...")
        invite_action.triggered.connect(
            lambda: self.open_invite_sender_dialog(selected))
        share_menu.addAction(invite_action)

        remove_action = QAction(QIcon(resource('close.png')),
                                "Remove from Recovery Key...")
        menu.addAction(open_action)
        menu.addMenu(share_menu)
        menu.addSeparator()
        menu.addAction(remove_action)
        if selection_is_remote:
            open_action.setEnabled(False)
            share_menu.setEnabled(False)
            remove_action.triggered.connect(
                lambda: self.confirm_unlink(selected))
        else:
            for folder in selected:
                if not self.gateway.magic_folders[folder]['admin_dircap']:
                    share_menu.setEnabled(False)
                    share_menu.setTitle(
                        "Sync with device (disabled; no admin access)")
            remove_action.setText('Stop syncing...')
            remove_action.triggered.connect(
                lambda: self.confirm_stop_syncing(selected))
        menu.exec_(self.viewport().mapToGlobal(position))
Beispiel #4
0
    def __init__(self, parent=None):
        super(InviteCodeLineEdit, self).__init__()
        self.parent = parent
        model = QStringListModel()
        model.setStringList(wordlist)
        completer = InviteCodeCompleter()
        completer.setModel(model)
        font = QFont()
        if sys.platform == 'darwin':
            font.setPointSize(20)
        else:
            font.setPointSize(16)
        self.setFont(font)
        self.setCompleter(completer)
        self.setAlignment(Qt.AlignCenter)
        #self.setPlaceholderText("Enter invite code")

        self.blank_icon = QIcon()
        self.paste_icon = QIcon(resource('paste.png'))
        self.clear_icon = QIcon(resource('close.png'))
        self.go_icon = QIcon(resource('arrow-right.png'))
        self.tor_icon = QIcon(resource('tor-onion.png'))

        self.status_action = QAction(self.blank_icon, '', self)
        self.addAction(self.status_action, 0)
        self.action_button = QAction(self.blank_icon, '', self)
        self.addAction(self.action_button, 1)

        completer.highlighted.connect(self.update_action_button)
        self.textChanged.connect(self.update_action_button)
        self.returnPressed.connect(self.return_pressed)
        self.action_button.triggered.connect(self.button_clicked)

        self.update_action_button()
Beispiel #5
0
 def __init__(self, parent=None):
     super(Delegate, self).__init__(parent=None)
     self.parent = parent
     self.waiting_movie = QMovie(resource('waiting.gif'))
     self.waiting_movie.setCacheMode(True)
     self.waiting_movie.frameChanged.connect(self.on_frame_changed)
     self.sync_movie = QMovie(resource('sync.gif'))
     self.sync_movie.setCacheMode(True)
     self.sync_movie.frameChanged.connect(self.on_frame_changed)
Beispiel #6
0
    def __init__(self, parent=None):
        super(WelcomeWidget, self).__init__()
        self.parent = parent

        self.icon = QLabel()
        pixmap = QPixmap(resource('gridsync.png')).scaled(220, 220)
        self.icon.setPixmap(pixmap)
        self.icon.setAlignment(Qt.AlignCenter)

        self.slogan = QLabel("<i>Secure, distributed storage</i>")
        font = QFont()
        font.setPointSize(12)
        self.slogan.setFont(font)
        self.slogan.setStyleSheet("color: grey")
        self.slogan.setAlignment(Qt.AlignCenter)

        self.invite_code_widget = InviteCodeWidget(self)
        self.lineedit = self.invite_code_widget.lineedit

        self.message = QLabel()
        self.message.setStyleSheet("color: red")
        self.message.setAlignment(Qt.AlignCenter)
        self.message.hide()

        self.help = QLabel()
        self.help.setText("<a href>I don't have an invite code</a>")
        font = QFont()
        font.setPointSize(9)
        self.help.setFont(font)
        self.help.setAlignment(Qt.AlignCenter)
        #self.help.linkActivated.connect(self.on_click)

        self.preferences_button = QPushButton()
        self.preferences_button.setIcon(QIcon(resource('preferences.png')))
        self.preferences_button.setStyleSheet('border: 0px; padding: 0px;')
        self.preferences_button.setToolTip("Preferences...")
        self.preferences_button.setFocusPolicy(Qt.NoFocus)

        layout = QGridLayout(self)
        layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 0, 0)
        layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1)
        layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 2)
        layout.addWidget(self.icon, 1, 3)
        layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 4)
        layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 5)
        layout.addWidget(self.slogan, 2, 3)
        layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 3, 1)
        layout.addWidget(self.invite_code_widget, 4, 2, 1, 3)
        layout.addWidget(self.message, 5, 3)
        layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Minimum), 6, 1)
        layout.addWidget(self.help, 7, 3)
        layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Minimum), 8, 1)
        layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 9, 1)
        layout.addWidget(self.preferences_button, 10, 5, Qt.AlignRight)
Beispiel #7
0
    def on_right_click(self, position):
        if not position:
            position = self.viewport().mapFromGlobal(QCursor().pos())
        cur_item = self.model().itemFromIndex(self.indexAt(position))
        if not cur_item:
            return
        cur_folder = self.model().item(cur_item.row(), 0).text()

        if self.gateway.magic_folders.get(cur_folder):  # is local folder
            selection_is_remote = False
            self.deselect_remote_folders()
        else:
            selection_is_remote = True
            self.deselect_local_folders()

        selected = self.get_selected_folders()
        if not selected:
            selected = [cur_folder]

        menu = QMenu()
        if selection_is_remote:
            download_action = QAction(
                QIcon(resource('download.png')), "Download...")
            download_action.triggered.connect(
                lambda: self.select_download_location(selected))
            menu.addAction(download_action)
            menu.addSeparator()
        open_action = QAction(self.model().icon_folder_gray, "Open")
        open_action.triggered.connect(
            lambda: self.open_folders(selected))
        share_action = QAction(QIcon(resource('share.png')), "Share...")
        share_action.triggered.connect(
            lambda: self.open_share_widget(selected))
        remove_action = QAction(QIcon(resource('close.png')), "Remove...")
        menu.addAction(open_action)
        menu.addAction(share_action)
        menu.addSeparator()
        menu.addAction(remove_action)
        if selection_is_remote:
            open_action.setEnabled(False)
            share_action.setEnabled(False)
            remove_action.triggered.connect(
                lambda: self.confirm_unlink(selected))
        else:
            for folder in selected:
                if not self.gateway.magic_folders[folder]['admin_dircap']:
                    share_action.setEnabled(False)
                    share_action.setText("Share (disabled; no admin access)")
            remove_action.triggered.connect(
                lambda: self.confirm_remove(selected))
        menu.exec_(self.viewport().mapToGlobal(position))
Beispiel #8
0
 def update_progress(self, step, message):
     self.step = step
     self.progressbar.setValue(step)
     self.message.setText(message)
     if step == 2:  # "Connecting to <nickname>..."
         pixmap = QPixmap(resource('lines_dotted.png')).scaled(128, 128)
         self.icon_connection.setPixmap(pixmap)
         pixmap = QPixmap(resource('cloud_storage.png')).scaled(220, 220)
         self.icon_server.setPixmap(pixmap)
     elif step == 5:  # "Done!"
         pixmap = QPixmap(resource('lines_solid.png')).scaled(128, 128)
         self.icon_connection.setPixmap(pixmap)
         pixmap = QPixmap(resource('green_checkmark.png')).scaled(32, 32)
         self.checkmark.setPixmap(pixmap)
Beispiel #9
0
 def update_action_button(self, text=None):
     text = (text if text else self.text())
     if not text:
         self.action_button.setIcon(QIcon())
         self.action_button.setToolTip('')
         for mode in get_clipboard_modes():
             if is_valid(get_clipboard_text(mode)):
                 self.action_button.setIcon(QIcon(resource('paste.png')))
                 self.action_button.setToolTip("Paste")
     elif is_valid(text):
         self.action_button.setIcon(QIcon(resource('arrow-right.png')))
         self.action_button.setToolTip("Go")
     else:
         self.action_button.setIcon(QIcon(resource('close.png')))
         self.action_button.setToolTip("Clear")
Beispiel #10
0
 def update_progress(self, message):
     step = self.progressbar.value() + 1
     self.progressbar.setValue(step)
     self.message.setText(message)
     if step == 2:  # "Connecting to <nickname>..."
         self.icon_connection.setPixmap(
             QPixmap(resource('lines_dotted.png')).scaled(128, 128))
         self.icon_server.setPixmap(
             QPixmap(resource('cloud_storage.png')).scaled(220, 220))
     elif step == 5:  # After await_ready()
         self.icon_connection.setPixmap(
             QPixmap(resource('lines_solid.png')).scaled(128, 128))
     elif step == self.progressbar.maximum():  # "Done!"
         self.checkmark.setPixmap(
             QPixmap(resource('green_checkmark.png')).scaled(32, 32))
Beispiel #11
0
    def __init__(self, parent):
        super(SystemTrayIcon, self).__init__()
        self.parent = parent

        self.icon = QIcon(resource(settings['application']['tray_icon']))
        self.setIcon(self.icon)

        self.menu = Menu(self)
        self.setContextMenu(self.menu)
        self.activated.connect(self.on_click)

        self.animation = QMovie()
        self.animation.setFileName(
            resource(settings['application']['tray_icon_sync']))
        self.animation.updated.connect(self.update)
        self.animation.setCacheMode(True)
Beispiel #12
0
def _dbus_notify(title, message, duration=5000):
    from PyQt5.QtDBus import (
        QDBus, QDBusArgument, QDBusConnection, QDBusInterface)
    bus = QDBusConnection.sessionBus()
    if not bus.isConnected():
        raise OSError("Could not connect to DBus")
    interface = QDBusInterface(
        'org.freedesktop.Notifications',
        '/org/freedesktop/Notifications',
        'org.freedesktop.Notifications',
        bus)
    error = interface.lastError()
    if error.type():
        raise RuntimeError("{}; {}".format(error.name(), error.message()))
    # See https://developer.gnome.org/notification-spec/
    # "This allows clients to effectively modify the notification while
    # it's active. A value of value of 0 means that this notification
    # won't replace any existing notifications."
    replaces_id = QVariant(0)
    replaces_id.convert(QVariant.UInt)
    interface.call(
        QDBus.NoBlock,
        'Notify',
        APP_NAME,
        replaces_id,
        resource(settings['application']['tray_icon']),
        title,
        message,
        QDBusArgument([], QMetaType.QStringList),
        {},
        duration)
Beispiel #13
0
    def __init__(self, parent=None):
        super(CodeEntryWidget, self).__init__()
        self.parent = parent

        self.icon = QLabel()
        pixmap = QPixmap(resource('gridsync.png')).scaled(220, 220)
        self.icon.setPixmap(pixmap)
        self.icon.setAlignment(Qt.AlignCenter)

        self.slogan = QLabel("<i>Secure, distributed storage</i>")
        font = QFont()
        font.setPointSize(12)
        self.slogan.setFont(font)
        self.slogan.setStyleSheet("color: grey")
        self.slogan.setAlignment(Qt.AlignCenter)

        self.label = QLabel("Enter invite code:")
        font = QFont()
        font.setPointSize(14)
        self.label.setFont(font)
        self.label.setStyleSheet("color: grey")
        self.label.setAlignment(Qt.AlignCenter)

        self.lineedit = InviteCodeLineEdit(self)

        self.checkbox = QCheckBox("Connect over the Tor network")
        self.checkbox.setEnabled(True)
        self.checkbox.setCheckable(False)
        self.checkbox.setStyleSheet("color: grey")
        self.checkbox.setFocusPolicy(Qt.NoFocus)

        self.message = QLabel()
        self.message.setStyleSheet("color: red")
        self.message.setAlignment(Qt.AlignCenter)
        self.message.hide()

        self.help = QLabel()
        self.help.setText("<a href>I don't have an invite code</a>")
        font = QFont()
        font.setPointSize(9)
        self.help.setFont(font)
        self.help.setAlignment(Qt.AlignCenter)
        #self.help.linkActivated.connect(self.on_click)

        layout = QGridLayout(self)
        layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 0, 0)
        layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1)
        layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 2)
        layout.addWidget(self.icon, 1, 3)
        layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 4)
        layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 5)
        layout.addWidget(self.slogan, 2, 3)
        layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 3, 1)
        layout.addWidget(self.label, 4, 3, 1, 1)
        layout.addWidget(self.lineedit, 5, 2, 1, 3)
        #layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 6, 1)
        #layout.addWidget(self.checkbox, 6, 3, 1, 1, Qt.AlignCenter)
        layout.addWidget(self.message, 7, 3)
        layout.addWidget(self.help, 8, 3)
        layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 9, 1)
Beispiel #14
0
    def __init__(self, gateway, deduplicate=True, max_items=30):
        super(HistoryListWidget, self).__init__()
        self.gateway = gateway
        self.deduplicate = deduplicate
        self.max_items = max_items

        palette = self.palette()
        self.base_color = palette.base().color()
        self.highlighted_color = BlendedColor(
            self.base_color, palette.highlight().color(), 0.88)  # Was #E6F1F7
        self.highlighted = None

        self.action_icon = QIcon(resource('dots-horizontal-triple.png'))

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.setFocusPolicy(Qt.NoFocus)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        #self.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.setSelectionMode(QAbstractItemView.NoSelection)
        #self.setStyleSheet("QListWidget::item:hover { background: #E6F1F7 }")
        self.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)

        self.sb = self.verticalScrollBar()

        self.sb.valueChanged.connect(self.update_visible_widgets)
        self.itemDoubleClicked.connect(self.on_double_click)
        self.customContextMenuRequested.connect(self.on_right_click)

        self.gateway.monitor.file_updated.connect(self.add_item)
        self.gateway.monitor.check_finished.connect(
            self.update_visible_widgets
        )
Beispiel #15
0
 def reset(self):
     self.progressbar.setValue(0)
     self.message.setText('')
     self.finish_button.hide()
     self.checkmark.setPixmap(QPixmap(resource('pixel.png')).scaled(32, 32))
     self.tor_label.hide()
     self.progressbar.setStyleSheet('')
Beispiel #16
0
 def on_done(self, gateway):
     self.gateway = gateway
     self.progressbar.setValue(self.progressbar.maximum())
     self.page_2.checkmark.setPixmap(
         QPixmap(resource('green_checkmark.png')).scaled(32, 32))
     self.finish_button.show()
     self.finish_button_clicked()  # TODO: Cleanup
Beispiel #17
0
    def __init__(self, parent=None, help_text='', show_stats=True):
        super(PasswordDialog, self).__init__(parent)
        self.setMinimumWidth(400)

        self.label = QLabel("Password:"******"Toggle visibility")
        self.action.triggered.connect(self.toggle_visibility)
        self.lineedit.addAction(self.action, QLineEdit.TrailingPosition)
        self.lineedit.returnPressed.connect(self.accept)

        layout = QGridLayout(self)
        layout.addWidget(self.label, 1, 1)
        layout.addWidget(self.lineedit, 2, 1)

        if show_stats:
            self.progressbar = QProgressBar()
            self.progressbar.setMaximum(4)
            self.progressbar.setTextVisible(False)
            self.progressbar.setFixedHeight(5)
            self.progressbar.setStyleSheet(
                'QProgressBar { background-color: transparent }'
                'QProgressBar::chunk { background-color: gray }')

            self.rating_label = QLabel()
            self.rating_label.setAlignment(Qt.AlignRight)

            self.time_label = QLabel()
            self.time_label.setStyleSheet('color: gray')

            layout.addWidget(self.progressbar, 3, 1)
            layout.addWidget(self.time_label, 4, 1)
            layout.addWidget(self.rating_label, 4, 1)

            self.lineedit.textChanged.connect(self.update_stats)

            self.update_color('transparent')

        if help_text:
            gbox = QGroupBox()
            gbox_layout = QGridLayout()
            gbox_label = QLabel(help_text)
            gbox_label.setWordWrap(True)
            gbox_label.setAlignment(Qt.AlignCenter)
            gbox_label.setStyleSheet('color: gray')
            gbox_layout.addWidget(gbox_label)
            gbox.setLayout(gbox_layout)
            layout.addWidget(gbox, 5, 1)

        layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 6, 1)
Beispiel #18
0
 def add_gateway(self, gateway):
     basename = os.path.basename(os.path.normpath(gateway.nodedir))
     icon = QIcon(os.path.join(gateway.nodedir, "icon"))
     if not icon.availableSizes():
         icon = QIcon(resource("tahoe-lafs.png"))
     self.insertItem(0, icon, basename, gateway)
     self.setCurrentIndex(0)
     self.current_index = 0
Beispiel #19
0
    def __init__(self, gateway, folder_name, data, parent):
        super(HistoryItemWidget, self).__init__()
        self.gateway = gateway
        self.data = data
        self.parent = parent

        self.path = data['path']
        self.size = data['size']
        self.action = data['action']
        self.mtime = data['mtime']
        self._thumbnail_loaded = False

        self.setAutoFillBackground(True)

        directory = self.gateway.get_magic_folder_directory(folder_name)
        if directory:
            self.path = os.path.join(directory, self.path)
        self.basename = os.path.basename(os.path.normpath(self.path))

        self.setToolTip("{}\n\nSize: {}\nModified: {}".format(
            self.path, naturalsize(self.size), time.ctime(self.mtime)))

        self.icon = QLabel()
        self.icon.setPixmap(QFileIconProvider().icon(QFileInfo(
            self.path)).pixmap(48, 48))

        self.basename_label = QLabel(self.basename)
        font = QFont()
        if sys.platform == 'darwin':
            font.setPointSize(15)
        else:
            font.setPointSize(11)
        self.basename_label.setFont(font)

        self.details_label = QLabel()
        font = QFont()
        if sys.platform == 'darwin':
            font.setPointSize(13)
        else:
            font.setPointSize(10)
        self.details_label.setFont(font)
        self.details_label.setStyleSheet('color: grey')

        self.button = QPushButton()
        self.button.setIcon(QIcon(resource('dots-horizontal-triple.png')))
        self.button.setStyleSheet('border: none;')
        self.button.clicked.connect(self.parent.on_right_click)
        self.button.hide()

        self.layout = QGridLayout(self)
        self.layout.addWidget(self.icon, 1, 1, 2, 2)
        self.layout.addWidget(self.basename_label, 1, 3)
        self.layout.addWidget(self.details_label, 2, 3)
        self.layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 4, 4)
        self.layout.addWidget(self.button, 1, 5, 2, 2)

        self.update_text()
        QTimer.singleShot(50, self.load_thumbnail)
Beispiel #20
0
    def join_grid(self, settings):
        nickname = settings['nickname']
        if self.use_tor:
            msg = "Connecting to {} via Tor...".format(nickname)
        else:
            msg = "Connecting to {}...".format(nickname)
        self.update_progress.emit(msg)

        icon_path = None
        if nickname == 'Least Authority S4':
            icon_path = resource('leastauthority.com.icon')
            self.got_icon.emit(icon_path)
        elif 'icon_base64' in settings:
            icon_path = os.path.join(config_dir, '.icon.tmp')
            self.decode_icon(settings['icon_base64'], icon_path)
        elif 'icon_url' in settings:
            # A temporary(?) measure to get around the performance issues
            # observed when transferring a base64-encoded icon through Least
            # Authority's wormhole server. Hopefully this will go away.. See:
            # https://github.com/LeastAuthority/leastauthority.com/issues/539
            log.debug("Fetching service icon from %s...", settings['icon_url'])
            icon_path = os.path.join(config_dir, '.icon.tmp')
            try:
                # It's probably not worth cancelling or holding-up the setup
                # process if fetching/writing the icon fails (particularly
                # if doing so would require the user to get a new invite code)
                # so just log a warning for now if something goes wrong...
                yield self.fetch_icon(settings['icon_url'], icon_path)
            except Exception as e:  # pylint: disable=broad-except
                log.warning("Error fetching service icon: %s", str(e))

        executable = yield select_executable()
        nodedir = os.path.join(config_dir, nickname)
        self.gateway = Tahoe(nodedir, executable=executable)
        yield self.gateway.create_client(**settings)

        newscap = settings.get('newscap')
        if newscap:
            with open(os.path.join(nodedir, 'private', 'newscap'), 'w') as f:
                f.write(newscap)

        if icon_path:
            try:
                shutil.copy(icon_path, os.path.join(nodedir, 'icon'))
            except OSError as err:
                log.warning("Error copying icon file: %s", str(err))
        if 'icon_url' in settings:
            try:
                with open(os.path.join(nodedir, 'icon.url'), 'w') as f:
                    f.write(settings['icon_url'])
            except OSError as err:
                log.warning("Error writing icon url to file: %s", str(err))

        self.update_progress.emit(msg)
        yield self.gateway.start()
        self.client_started.emit(self.gateway)
        self.update_progress.emit(msg)
        yield self.gateway.await_ready()
Beispiel #21
0
 def show_news_message(self, gateway, title, message):
     msgbox = QMessageBox(self)
     msgbox.setWindowModality(Qt.WindowModal)
     icon_filepath = os.path.join(gateway.nodedir, 'icon')
     if os.path.exists(icon_filepath):
         msgbox.setIconPixmap(QIcon(icon_filepath).pixmap(64, 64))
     elif os.path.exists(resource('tahoe-lafs.png')):
         msgbox.setIconPixmap(
             QIcon(resource('tahoe-lafs.png')).pixmap(64, 64))
     else:
         msgbox.setIcon(QMessageBox.Information)
     if sys.platform == 'darwin':
         msgbox.setText(title)
         msgbox.setInformativeText(message)
     else:
         msgbox.setWindowTitle(title)
         msgbox.setText(message)
     msgbox.show()
Beispiel #22
0
    def __init__(self, parent=None):
        super(InviteCodeWidget, self).__init__()
        self.parent = parent

        self.label = QLabel("Enter invite code:")
        font = QFont()
        if sys.platform == 'darwin':
            font.setPointSize(18)
        else:
            font.setPointSize(14)
        self.label.setFont(font)
        self.label.setStyleSheet("color: grey")
        self.label.setAlignment(Qt.AlignCenter)

        self.lineedit = InviteCodeLineEdit(self)

        self.checkbox = QCheckBox("Connect over the Tor network")
        self.checkbox.setStyleSheet("QCheckBox { color: dimgrey }")
        self.checkbox.setFocusPolicy(Qt.NoFocus)

        self.tor_info_text = (
            "Tor is an anonymizing network that helps defend against network "
            "surveillance and traffic analysis. With this checkbox enabled, "
            "Gridsync will route all traffic corresponding to this connection "
            "through the Tor network, concealing your geographical location "
            "from your storage provider and other parties (such as any "
            "persons with whom you might share folders).<p>"
            "Using this option requires that Tor already be installed and "
            "running on your computer and may be slower or less reliable than "
            "your normal internet connection.<p>"
            "For more information or to download Tor, please visit "
            "<a href=https://torproject.org>https://torproject.org</a>")

        self.tor_info_button = QPushButton()
        self.tor_info_button.setFlat(True)
        self.tor_info_button.setIcon(QIcon(resource('question')))
        self.tor_info_button.setIconSize(QSize(13, 13))
        self.tor_info_button.setFixedSize(13, 13)
        self.tor_info_button.setToolTip(self.tor_info_text)
        self.tor_info_button.clicked.connect(self.on_tor_info_button_clicked)
        self.tor_info_button.setFocusPolicy(Qt.NoFocus)

        tor_layout = QGridLayout()
        tor_layout.setHorizontalSpacing(0)
        tor_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1)
        tor_layout.addWidget(self.checkbox, 1, 2, Qt.AlignCenter)
        tor_layout.addWidget(self.tor_info_button, 1, 3, Qt.AlignLeft)
        tor_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 4)

        layout = QGridLayout(self)
        layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 1, 1)
        layout.addWidget(self.label, 2, 1)
        layout.addWidget(self.lineedit, 3, 1)
        layout.addLayout(tor_layout, 4, 1)
        layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 5, 1)

        self.checkbox.stateChanged.connect(self.toggle_tor_status)
Beispiel #23
0
    def __init__(self, gateway, folder_name, data, parent):
        super().__init__()
        self.gateway = gateway
        self.data = data
        self.parent = parent

        self.path = data["path"]
        self.size = data["size"]
        self.action = data["action"]
        self.mtime = data["mtime"]
        self._thumbnail_loaded = False

        self.setAutoFillBackground(True)

        directory = self.gateway.get_magic_folder_directory(folder_name)
        if directory:
            self.path = os.path.join(directory, self.path)
        self.basename = os.path.basename(os.path.normpath(self.path))

        self.setToolTip(
            "{}\n\nSize: {}\nModified: {}".format(
                self.path, naturalsize(self.size), time.ctime(self.mtime)
            )
        )

        self.icon = QLabel()
        self.icon.setPixmap(
            QFileIconProvider().icon(QFileInfo(self.path)).pixmap(48, 48)
        )

        self.basename_label = QLabel(self.basename)
        self.basename_label.setFont(Font(11))

        self.details_label = QLabel()
        self.details_label.setFont(Font(10))
        palette = self.palette()
        dimmer_grey = BlendedColor(
            palette.text().color(), palette.base().color(), 0.6
        ).name()
        self.details_label.setStyleSheet("color: {}".format(dimmer_grey))

        self.button = QPushButton()
        self.button.setIcon(QIcon(resource("dots-horizontal-triple.png")))
        self.button.setStyleSheet("border: none;")
        self.button.clicked.connect(self.parent.on_right_click)
        self.button.hide()

        self.layout = QGridLayout(self)
        self.layout.addWidget(self.icon, 1, 1, 2, 2)
        self.layout.addWidget(self.basename_label, 1, 3)
        self.layout.addWidget(self.details_label, 2, 3)
        self.layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 4, 4)
        self.layout.addWidget(self.button, 1, 5, 2, 2)

        self.update_text()
        QTimer.singleShot(50, self.load_thumbnail)
Beispiel #24
0
 def populate(self, gateways):
     self.clear()
     for gateway in gateways:
         basename = os.path.basename(os.path.normpath(gateway.nodedir))
         icon = QIcon(os.path.join(gateway.nodedir, 'icon'))
         if not icon.availableSizes():
             icon = QIcon(resource('tahoe-lafs.png'))
         self.addItem(icon, basename, gateway)
     self.insertSeparator(self.count())
     self.addItem(" Add new...")
Beispiel #25
0
 def update_folder_icon(self, folder_name, folder_path, overlay_file=None):
     items = self.findItems(folder_name)
     if items:
         folder_icon = QFileIconProvider().icon(QFileInfo(folder_path))
         folder_pixmap = folder_icon.pixmap(256, 256)
         if overlay_file:
             pixmap = CompositePixmap(folder_pixmap, resource(overlay_file))
         else:
             pixmap = CompositePixmap(folder_pixmap)
         items[0].setIcon(QIcon(pixmap))
Beispiel #26
0
    def __init__(self, view):
        super().__init__(0, 5)
        self.view = view
        self.gui = self.view.gui
        self.gateway = self.view.gateway
        self.monitor = self.gateway.monitor
        self.status_dict = {}
        self.members_dict = {}
        self.grid_status = ""
        self.available_space = 0
        self.setHeaderData(0, Qt.Horizontal, "Name")
        self.setHeaderData(1, Qt.Horizontal, "Status")
        self.setHeaderData(2, Qt.Horizontal, "Last modified")
        self.setHeaderData(3, Qt.Horizontal, "Size")
        self.setHeaderData(4, Qt.Horizontal, "")

        self.icon_blank = QIcon()
        self.icon_up_to_date = QIcon(resource("checkmark.png"))
        self.icon_user = QIcon(resource("user.png"))
        self.icon_folder = QFileIconProvider().icon(QFileInfo(config_dir))
        composite_pixmap = CompositePixmap(
            self.icon_folder.pixmap(256, 256), overlay=None, grayout=True
        )
        self.icon_folder_gray = QIcon(composite_pixmap)
        self.icon_cloud = QIcon(resource("cloud-icon.png"))
        self.icon_action = QIcon(resource("dots-horizontal-triple.png"))

        self.monitor.connected.connect(self.on_connected)
        self.monitor.disconnected.connect(self.on_disconnected)
        self.monitor.nodes_updated.connect(self.on_nodes_updated)
        self.monitor.space_updated.connect(self.on_space_updated)
        self.monitor.status_updated.connect(self.set_status)
        self.monitor.mtime_updated.connect(self.set_mtime)
        self.monitor.size_updated.connect(self.set_size)
        self.monitor.members_updated.connect(self.on_members_updated)
        self.monitor.sync_started.connect(self.on_sync_started)
        self.monitor.sync_finished.connect(self.on_sync_finished)
        self.monitor.files_updated.connect(self.on_updated_files)
        self.monitor.check_finished.connect(self.update_natural_times)
        self.monitor.remote_folder_added.connect(self.add_remote_folder)
        self.monitor.transfer_progress_updated.connect(
            self.set_transfer_progress
        )
Beispiel #27
0
    def __init__(self):
        super(PreferencesWindow, self).__init__()
        self.setMinimumSize(500, 300)
        self.setUnifiedTitleAndToolBarOnMac(True)

        self.toolbar = self.addToolBar("")
        self.toolbar.setIconSize(QSize(36, 36))
        self.toolbar.setMovable(False)
        self.toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)

        self.general_button = QToolButton(self)
        self.general_button.setDefaultAction(
            QAction(QIcon(resource("preferences.png")), "General")
        )
        self.general_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.general_button.setCheckable(True)
        self.general_button.triggered.connect(self.on_general_button_clicked)

        self.notifications_button = QToolButton(self)
        self.notifications_button.setDefaultAction(
            QAction(QIcon(resource("notification.png")), "Notifications")
        )
        self.notifications_button.setToolButtonStyle(
            Qt.ToolButtonTextUnderIcon
        )
        self.notifications_button.setCheckable(True)
        self.notifications_button.triggered.connect(
            self.on_notifications_button_clicked
        )

        self.toolbar.addWidget(self.general_button)
        self.toolbar.addWidget(self.notifications_button)

        self.general_pane = GeneralPane()
        self.notifications_pane = NotificationsPane()

        self.stacked_widget = QStackedWidget()
        self.stacked_widget.addWidget(self.general_pane)
        self.stacked_widget.addWidget(self.notifications_pane)
        self.setCentralWidget(self.stacked_widget)

        self.on_general_button_clicked()
Beispiel #28
0
    def __init__(self, gui):
        super(SystemTrayIcon, self).__init__()
        self.gui = gui

        tray_icon_path = resource(settings['application']['tray_icon'])
        self.app_pixmap = QPixmap(tray_icon_path)
        self.app_icon = QIcon(tray_icon_path)
        self.setIcon(self.app_icon)

        self.menu = Menu(self.gui)
        self.setContextMenu(self.menu)
        self.activated.connect(self.on_click)

        self.messageClicked.connect(self.gui.show_main_window)

        self.animation = QMovie()
        self.animation.setFileName(
            resource(settings['application']['tray_icon_sync']))
        self.animation.updated.connect(self.update)
        self.animation.setCacheMode(True)
Beispiel #29
0
def test_join_grid_emit_got_icon_signal_nickname_least_authority_s4(
        monkeypatch, qtbot, tmpdir):
    monkeypatch.setattr('gridsync.setup.select_executable', lambda:
                        (None, None))
    monkeypatch.setattr('gridsync.setup.config_dir',
                        str(tmpdir.mkdir('config_dir')))
    monkeypatch.setattr('gridsync.setup.Tahoe', MagicMock())
    sr = SetupRunner([])
    settings = {'nickname': 'Least Authority S4'}
    with qtbot.wait_signal(sr.got_icon) as blocker:
        yield sr.join_grid(settings)
    assert blocker.args == [resource('leastauthority.com.icon')]
Beispiel #30
0
    def __init__(self, view):
        super(Model, self).__init__(0, 4)
        self.view = view
        self.gui = self.view.gui
        self.gateway = self.view.gateway
        self.monitor = Monitor(self.gateway)
        self.status_dict = {}
        self.grid_status = ''
        self.available_space = 0
        self.setHeaderData(0, Qt.Horizontal, "Name")
        self.setHeaderData(1, Qt.Horizontal, "Status")
        self.setHeaderData(2, Qt.Horizontal, "Last modified")
        self.setHeaderData(3, Qt.Horizontal, "Size")
        #self.setHeaderData(4, Qt.Horizontal, "Action")

        self.icon_blank = QIcon()
        self.icon_up_to_date = QIcon(resource('checkmark.png'))
        self.icon_user = QIcon(resource('user.png'))
        self.icon_folder = QFileIconProvider().icon(QFileInfo(config_dir))
        composite_pixmap = CompositePixmap(self.icon_folder.pixmap(256, 256),
                                           overlay=None,
                                           grayout=True)
        self.icon_folder_gray = QIcon(composite_pixmap)

        self.monitor.connected.connect(self.on_connected)
        self.monitor.disconnected.connect(self.on_disconnected)
        self.monitor.nodes_updated.connect(self.on_nodes_updated)
        self.monitor.space_updated.connect(self.on_space_updated)
        self.monitor.data_updated.connect(self.set_data)
        self.monitor.status_updated.connect(self.set_status)
        self.monitor.mtime_updated.connect(self.set_mtime)
        self.monitor.size_updated.connect(self.set_size)
        #self.monitor.member_added.connect(self.add_member)  # XXX
        self.monitor.first_sync_started.connect(self.on_first_sync)
        self.monitor.sync_started.connect(self.on_sync_started)
        self.monitor.sync_finished.connect(self.on_sync_finished)
        self.monitor.files_updated.connect(self.on_updated_files)
        self.monitor.check_finished.connect(self.update_natural_times)
        self.monitor.remote_folder_added.connect(self.add_remote_folder)