Ejemplo n.º 1
0
class DownloadProgress(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setVisible(False)
        self.l = QVBoxLayout(self)
        self.items = {}

    def add_item(self, download_id, filename):
        self.setVisible(True)
        item = DownloadItem(download_id, filename, self)
        self.l.addWidget(item)
        self.items[download_id] = item

    def update_item(self, download_id, done, total):
        item = self.items.get(download_id)
        if item is not None:
            item(done, total)

    def remove_item(self, download_id):
        item = self.items.pop(download_id, None)
        if item is not None:
            self.l.removeWidget(item)
            item.setVisible(False)
            item.setParent(None)
            item.deleteLater()
        if not self.items:
            self.setVisible(False)
Ejemplo n.º 2
0
class SearchTheInternet(QWidget):

    changed_signal = pyqtSignal()

    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.sa = QScrollArea(self)
        self.lw = QWidget(self)
        self.l = QVBoxLayout(self.lw)
        self.sa.setWidget(self.lw), self.sa.setWidgetResizable(True)
        self.gl = gl = QVBoxLayout(self)
        self.la = QLabel(_(
            'Add new locations to search for books or authors using the "Search the internet" feature'
            ' of the Content server. The URLs should contain {author} which will be'
            ' replaced by the author name and, for book URLs, {title} which will'
            ' be replaced by the book title.'))
        self.la.setWordWrap(True)
        gl.addWidget(self.la)

        self.h = QHBoxLayout()
        gl.addLayout(self.h)
        self.add_url_button = b = QPushButton(QIcon(I('plus.png')), _('&Add URL'))
        b.clicked.connect(self.add_url)
        self.h.addWidget(b)
        self.export_button = b = QPushButton(_('Export URLs'))
        b.clicked.connect(self.export_urls)
        self.h.addWidget(b)
        self.import_button = b = QPushButton(_('Import URLs'))
        b.clicked.connect(self.import_urls)
        self.h.addWidget(b)
        self.clear_button = b = QPushButton(_('Clear'))
        b.clicked.connect(self.clear)
        self.h.addWidget(b)

        self.h.addStretch(10)
        gl.addWidget(self.sa, stretch=10)
        self.items = []

    def genesis(self):
        self.current_urls = search_the_net_urls() or []

    @property
    def current_urls(self):
        return [item.as_dict for item in self.items if not item.is_empty]

    def append_item(self, item_as_dict):
        self.items.append(URLItem(item_as_dict, self))
        self.l.addWidget(self.items[-1])

    def clear(self):
        [(self.l.removeWidget(w), w.setParent(None), w.deleteLater()) for w in self.items]
        self.items = []
        self.changed_signal.emit()

    @current_urls.setter
    def current_urls(self, val):
        self.clear()
        for entry in val:
            self.append_item(entry)

    def add_url(self):
        self.items.append(URLItem(None, self))
        self.l.addWidget(self.items[-1])
        QTimer.singleShot(100, self.scroll_to_bottom)

    def scroll_to_bottom(self):
        sb = self.sa.verticalScrollBar()
        if sb:
            sb.setValue(sb.maximum())
        self.items[-1].name_widget.setFocus(Qt.OtherFocusReason)

    @property
    def serialized_urls(self):
        return json.dumps(self.current_urls, indent=2)

    def commit(self):
        for item in self.items:
            if not item.validate():
                return False
        cu = self.current_urls
        if cu:
            with lopen(search_the_net_urls.path, 'wb') as f:
                f.write(self.serialized_urls)
        else:
            try:
                os.remove(search_the_net_urls.path)
            except EnvironmentError as err:
                if err.errno != errno.ENOENT:
                    raise
        return True

    def export_urls(self):
        path = choose_save_file(
            self, 'search-net-urls', _('Choose URLs file'),
            filters=[(_('URL files'), ['json'])], initial_filename='search-urls.json')
        if path:
            with lopen(path, 'wb') as f:
                f.write(self.serialized_urls)

    def import_urls(self):
        paths = choose_files(self, 'search-net-urls', _('Choose URLs file'),
            filters=[(_('URL files'), ['json'])], all_files=False, select_only_single_file=True)
        if paths:
            with lopen(paths[0], 'rb') as f:
                items = json.loads(f.read())
                [self.append_item(x) for x in items]
                self.changed_signal.emit()
Ejemplo n.º 3
0
class PlayWidget(QWidget):
    def __init__(self, parent):
        super(PlayWidget, self).__init__(parent)
        self.setAutoFillBackground(True)
        self.hlayout = QHBoxLayout(self)

        self.table_view = CardView(self)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.table_view.sizePolicy().hasHeightForWidth())
        self.table_view.setSizePolicy(sizePolicy)
        self.table_view.setMinimumHeight(200)
        self.table_view.setBackgroundBrush(Qt.darkGreen)
        self.table_view.setGeometry(0, 0, 1028, 200)

        self.hand_view = HandCardView(self)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.hand_view.sizePolicy().hasHeightForWidth())
        self.hand_view.setSizePolicy(sizePolicy)
        self.hand_view.setMinimumHeight(200)
        self.hand_view.setBackgroundBrush(Qt.darkGreen)
        self.hand_view.setGeometry(0, 0, 1028, 200)

        self.show_button = Button(self, 'Show Hand')
        self.show_button.setText("Show hand")
        self.show_button.clicked.connect(self.hand_view.show_cards)
        self.show_button.hide()

        self.move_button = Button(self, 'Make Move')
        self.move_button.setMinimumSize(300, 100)
        self.move_button.clicked.connect(self.attempt_move)
        self.move_button.hide()

        self.start_button = Button(self, 'Start Round')
        self.start_button.setMinimumHeight(100)
        self.start_button.clicked.connect(self.start_round)

        self.next_button = Button(self, 'Continue')
        self.next_button.setMinimumHeight(100)
        self.next_button.clicked.connect(self.goto_next_round)
        self.next_button.hide()

        self.quit_button = Button(self, 'Quit to menu')

        self.save_button = Button(self, 'Save')

        self.show_button.setMaximumWidth(150)
        self.move_button.setMaximumWidth(150)
        self.quit_button.setMaximumWidth(150)

        self.btnlayout = QHBoxLayout()
        self.btnlayout.addWidget(self.start_button)

        self.btn2layout = QHBoxLayout()
        self.btn2layout.addWidget(self.save_button)
        self.btn2layout.addWidget(self.quit_button)

        self.playlayout = QVBoxLayout()
        self.playlayout.addWidget(self.table_view)
        self.playlayout.addLayout(self.btnlayout)
        self.playlayout.addWidget(self.hand_view)
        self.playlayout.addLayout(self.btn2layout)
        self.hlayout.addLayout(self.playlayout)

        self.sidelayout = QVBoxLayout()
        self.log = QPlainTextEdit()
        self.log.setReadOnly(True)
        self.log.setPalette(QPalette(Qt.white))
        self.log.setMaximumWidth(300)
        self.log.setMaximumHeight(200)
        self.sidelayout.addWidget(self.log)

        self.playerinfolayout = QVBoxLayout()
        self.sidelayout.addLayout(self.playerinfolayout)

        self.sidelayout.addItem(
            QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding))

        self.hlayout.addLayout(self.sidelayout)

        self.setup_sound()

        self.move_count = 0
        self.speed = 3
        self.game = None

    def init_game(self, game):
        self.game = game
        self.game.logSignal.connect(self.update_log)
        self.game.sweepSignal.connect(self.sweep_sound.play)

        self.game.new_round()
        self.shuffle_sound.play()
        self.game.initial_deal()

        self.move_count = 0

        for player in self.game.players:
            self.playerinfolayout.addWidget(PlayerInfo(self, player))

    def start_round(self):
        self.btnlayout.removeWidget(self.start_button)
        self.btnlayout.insertWidget(0, self.show_button)
        self.btnlayout.insertWidget(1, self.move_button)
        self.start_button.hide()
        self.show_button.show()
        self.move_button.show()

        self.table_view.update_scene(self.game.table)
        self.hand_view.update_scene(self.game.current_player.hand)

        self.hand_view.hide_cards()

        if type(self.game.current_player
                ) is not AIPlayer and self.game.one_human:
            self.hand_view.show_cards()

        self.playerinfolayout.itemAt(
            self.game.players.index(
                self.game.current_player)).widget().set_active()
        self.update_log('\n----------\n{}\'s turn\n'.format(
            self.game.current_player))

        if type(self.game.current_player) is AIPlayer:
            self.move_button.setDisabled(True)
            self.show_button.setDisabled(True)
            self.save_button.setDisabled(True)
            self.make_ai_move()

    def resume_from_save(self, game, logmsg, movecount):
        self.game = game
        self.game.logSignal.connect(self.update_log)
        self.game.sweepSignal.connect(self.sweep_sound.play)

        self.log.insertPlainText(logmsg)
        self.log.insertPlainText(
            '\n----------------\n    Resuming from save\n----------------\n\n')

        self.move_count = movecount

        for player in self.game.players:
            self.playerinfolayout.addWidget(PlayerInfo(self, player))

        self.playerinfolayout.itemAt(
            self.game.players.index(
                self.game.current_player)).widget().set_active()

    def make_ai_move(self):
        self.game.select_move_for_ai()
        QTimer.singleShot(1500 // self.speed, self.show_ai_move)

    def show_ai_move(self):
        self.hand_view.auto_select()
        self.table_view.auto_select()
        self.card_sound.play()
        self.game.do_action()
        QTimer.singleShot(3000 // self.speed, self.after_ai_move_done)

    def after_ai_move_done(self):
        self.move_sound.play()
        self.playerinfolayout.itemAt(
            self.game.players.index(
                self.game.current_player)).widget().update_info()
        self.game.deal()
        self.table_view.update_scene(self.game.table)
        self.hand_view.update_scene(self.game.current_player.hand)
        self.hand_view.hide_cards()
        QTimer.singleShot(3000 // self.speed, self.end_turn)

    def attempt_move(self):
        if self.game.do_action():
            self.move_sound.play()
            self.playerinfolayout.itemAt(
                self.game.players.index(
                    self.game.current_player)).widget().update_info()
            self.move_button.setDisabled(True)
            self.table_view.update_scene(self.game.table)
            self.hand_view.update_scene(self.game.current_player.hand)
            QTimer.singleShot(1800 // self.speed, self.after_move_done)

        else:
            self.error_sound.play()

    def after_move_done(self):
        self.game.deal()
        self.hand_view.update_scene(self.game.current_player.hand)
        QTimer.singleShot(3000 // self.speed, self.end_turn)

    def end_turn(self):
        self.playerinfolayout.itemAt(
            self.game.players.index(
                self.game.current_player)).widget().set_inactive()
        self.game.next_player()
        self.playerinfolayout.itemAt(
            self.game.players.index(
                self.game.current_player)).widget().set_active()

        self.move_button.setDisabled(False)
        self.show_button.setDisabled(False)
        self.table_view.deselect_all()

        self.move_count += 1
        if self.move_count == 48:
            self.end_round()
            return

        self.update_log('\n----------\n{}\'s turn\n'.format(
            self.game.current_player))
        self.hand_view.update_scene(self.game.current_player.hand)
        self.hand_view.hide_cards()

        #if there is only one human player, his/her cards are shown automatically
        if type(self.game.current_player
                ) is not AIPlayer and self.game.one_human:
            self.hand_view.show_cards()
            self.alert_sound.play()

        if type(self.game.current_player) is AIPlayer:
            self.move_button.setDisabled(True)
            self.show_button.setDisabled(True)
            self.save_button.setDisabled(True)
            self.make_ai_move()
            return

        self.save_button.setDisabled(False)

    def end_round(self):
        self.save_button.setDisabled(True)
        self.playerinfolayout.itemAt(
            self.game.players.index(
                self.game.current_player)).widget().set_inactive()
        self.end_sound.play()
        game_ended = self.game.end_round()
        for i in range(self.playerinfolayout.count()):
            self.playerinfolayout.itemAt(i).widget().update_info()
            self.playerinfolayout.itemAt(i).widget().update_score()

        self.table_view.update_scene(self.game.table)

        self.btnlayout.removeWidget(self.show_button)
        self.btnlayout.removeWidget(self.move_button)
        self.btnlayout.insertWidget(0, self.next_button)
        self.next_button.show()
        self.show_button.hide()
        self.move_button.hide()
        if game_ended:
            self.next_button.setDisabled(True)

    def goto_next_round(self):
        self.save_button.setDisabled(False)
        self.btnlayout.removeWidget(self.next_button)
        self.btnlayout.insertWidget(0, self.start_button)
        self.start_button.show()
        self.next_button.hide()

        #rotate playerinfo
        mov = self.playerinfolayout.itemAt(0).widget()
        self.playerinfolayout.removeWidget(mov)
        self.playerinfolayout.addWidget(mov)

        self.game.new_round()
        self.shuffle_sound.play()

        for i in range(self.playerinfolayout.count()):
            self.playerinfolayout.itemAt(i).widget().update_info()

        self.game.new_round()
        self.game.initial_deal()

        self.move_count = 0

    def setup_sound(self):
        self.shuffle_sound = QSoundEffect()
        self.shuffle_sound.setSource(QUrl.fromLocalFile('sound/shuffle.wav'))

        self.error_sound = QSoundEffect()
        self.error_sound.setSource(QUrl.fromLocalFile('sound/error.wav'))

        self.move_sound = QSoundEffect()
        self.move_sound.setSource(QUrl.fromLocalFile('sound/draw.wav'))

        self.card_sound = QSoundEffect()
        self.card_sound.setSource(QUrl.fromLocalFile('sound/playcard.wav'))

        self.sweep_sound = QSoundEffect()
        self.sweep_sound.setSource(QUrl.fromLocalFile('sound/sweep.wav'))

        self.alert_sound = QSoundEffect()
        self.alert_sound.setSource(QUrl.fromLocalFile('sound/alert.wav'))

        self.end_sound = QSoundEffect()
        self.end_sound.setSource(QUrl.fromLocalFile('sound/endturn.wav'))

    def reset(self):
        self.game = None

    def update_log(self, msg):
        self.log.insertPlainText(msg)
        self.log.ensureCursorVisible()  #auto-scrolls to bottom of log

    def export_log(self):
        return self.log.toPlainText()
Ejemplo n.º 4
0
class ConfigWidget(QWidget):
    def __init__(self):
        self.plugin_prefs = prefs
        self.restart_required = False
        self.inspector = None

        QWidget.__init__(self)
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        #add checkbox
        self.inspector_checkbox = QCheckBox('Show Inspector')
        self.inspector_checkbox.setChecked(
            self.plugin_prefs.get('inspector_enabled', False))
        self.inspector_checkbox.stateChanged.connect(
            self._inspector_enabled_changed)
        self.inspector_checkbox.setToolTip(
            'Enable Javascript Console for debugging WebView requests to QuietThyme API'
        )
        self.l.addWidget(self.inspector_checkbox)

        self.beta_checkbox = QCheckBox('Beta Mode')
        self.beta_checkbox.setChecked(self.plugin_prefs.get(
            'beta_mode', False))
        self.beta_checkbox.stateChanged.connect(self._set_restart_required)
        self.beta_checkbox.stateChanged.connect(self._beta_mode_changed)
        self.beta_checkbox.setToolTip(
            'Tell Calibre to communicate with the Beta version of QuietThyme')
        self.l.addWidget(self.beta_checkbox)

        self.config_url = QUrl(self.plugin_prefs.get('web_base') + '/storage')
        self.webview = QTWebView(bearer_token=self.plugin_prefs.get('token'))

        self.webview.load(self.config_url)
        self.global_settings = self.webview.page().settings(
        )  #QWebSettings.globalSettings()

        self.global_settings.setAttribute(
            QWebSettings.LocalStorageEnabled,
            True)  #required since this is where we store tokens.
        self.global_settings.setAttribute(QWebSettings.PrivateBrowsingEnabled,
                                          False)
        self.global_settings.setAttribute(QWebSettings.JavascriptEnabled, True)
        self.global_settings.setAttribute(
            QWebSettings.JavascriptCanOpenWindows, True)
        self.global_settings.setAttribute(
            QWebSettings.JavascriptCanCloseWindows, True)
        self.global_settings.setAttribute(QWebSettings.PluginsEnabled, True)
        self.global_settings.setAttribute(
            QWebSettings.LocalContentCanAccessRemoteUrls, True)
        self.global_settings.setAttribute(
            QWebSettings.LocalContentCanAccessFileUrls, True)
        self.global_settings.setAttribute(QWebSettings.XSSAuditingEnabled,
                                          False)
        self.global_settings.setAttribute(QWebSettings.DeveloperExtrasEnabled,
                                          True)

        # ensure that we get a random offline/localstorage/cache path for the brower (so that the localstorage data is not persistent across sessions)
        path = None
        while True:
            potential_path = QTemporaryDir()
            if potential_path.isValid():
                path = potential_path.path()
                break

        self.global_settings.setOfflineStoragePath(path)
        self.global_settings.setOfflineWebApplicationCachePath(path)
        self.global_settings.enablePersistentStorage(path)
        self.global_settings.setLocalStoragePath(path)

        self.webview.show()
        self.l.addWidget(self.webview)

        self.configure_webview_inspector_ui()

        self.webview.urlChanged.connect(self._url_changed)
        self.webview.loadFinished.connect(self._load_finished)

    ################################################################################################################
    # Configure UI methods
    #
    def configure_webview_inspector_ui(self):
        if self.plugin_prefs.get('inspector_enabled'):
            self.webview.setMinimumSize(QSize(600, 300))
            self.inspector = QWebInspector()
            self.inspector.setMinimumSize(QSize(600, 300))
            self.inspector.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Expanding)
            self.l.addWidget(self.inspector)
            self.inspector.setPage(self.webview.page())
        else:
            self.webview.setMinimumSize(QSize(600, 600))
            if self.inspector is not None:
                self.l.removeWidget(self.inspector)
                self.inspector.setParent(None)
                self.inspector = None

    def save_settings(self):
        self.plugin_prefs.set('inspector_enabled',
                              self.inspector_checkbox.isChecked())
        self.plugin_prefs.set('beta_mode', self.beta_checkbox.isChecked())

        # # If restart needed, inform user
        if self.restart_required:
            # do_restart = show_restart_warning('Restart calibre for the changes to be applied.',
            #                                   parent=self.l)
            # if do_restart:
            #     self.gui.quit(restart=True)

            # TODO: figure out if theres a way to call self.gui.quit()

            msg = QMessageBox()
            msg.setIcon(QMessageBox.Warning)

            msg.setText("Restart Required")
            msg.setInformativeText(
                "A configuration change requires you to restart Calibre, You should do so now,"
            )
            msg.setWindowTitle("Restart Required")
            msg.setStandardButtons(QMessageBox.Ok)
            msg.exec_()

    def validate(self):
        # TODO: validate the that the api_endpoint and web endpoint are valid urls.
        return True

    ################################################################################################################
    # Event Handlers
    #
    def _url_changed(self, url):
        logger.debug(sys._getframe().f_code.co_name, url)

    def _load_finished(self, ok):
        logger.debug(sys._getframe().f_code.co_name, ok)
        if self.webview.page().mainFrame().url() == self.config_url:
            logger.debug(
                "Loading finished and the url is the same as the desired destination url, ",
                self.config_url)
            self.webview.page().mainFrame().evaluateJavaScript("""
            console.log("GET LOCALSTORAGE TOKEN")
            """)
            token = self.webview.page().mainFrame().evaluateJavaScript("""
            localStorage.getItem('id_token');
            """)
            logger.debug("Got JWT Token", token)
            self.plugin_prefs.set('token', token)

    def _set_restart_required(self, state):
        '''
        Set restart_required flag to show show dialog when closing dialog
        '''

        logger.debug(sys._getframe().f_code.co_name, "restart required")
        self.restart_required = True

    def _beta_mode_changed(self, state):
        logger.debug(sys._getframe().f_code.co_name,
                     self.beta_checkbox.isChecked())
        self.plugin_prefs.set('beta_mode', self.beta_checkbox.isChecked())

        # if the beta mode has changed, we need to reset the api endpoints, and then wipe the token (not valid between envs)
        self.plugin_prefs.set('token', '')
        if self.plugin_prefs.get('beta_mode'):
            self.plugin_prefs.set('api_base', beta_api_base)
            self.plugin_prefs.set('web_base', beta_web_base)
        else:
            self.plugin_prefs.set('api_base', master_api_base)
            self.plugin_prefs.set('web_base', master_web_base)

        # after we reset the token, we need to generate a new QTWebView with the new config, and then reload the login page.
        self.config_url = QUrl(self.plugin_prefs.get('web_base') + '/storage')

        self.webview.set_bearer_token(self.plugin_prefs.get('token'))
        self.webview.load(self.config_url)

    def _inspector_enabled_changed(self, state):
        logger.debug(sys._getframe().f_code.co_name,
                     self.inspector_checkbox.isChecked())
        self.plugin_prefs.set('inspector_enabled',
                              self.inspector_checkbox.isChecked())
        self.configure_webview_inspector_ui()
Ejemplo n.º 5
0
class StartMenu(QWidget):
    
    def __init__(self, parent):
        super(StartMenu, self).__init__(parent)
        
        self.tophbox = QHBoxLayout()
        self.hbox = QHBoxLayout()
        self.vbox = QVBoxLayout()
        
        self.label = QLabel()
        self.label.setPixmap(QPixmap('img/new-game.png'))
        self.label.setScaledContents(True)
        self.label.setFixedSize(600, 200)
        self.tophbox.addWidget(self.label)
        
        self.startbutton = Button(self, 'Start')
        self.startbutton.setEnabled(False)
        self.startbutton.setFixedHeight(100)
        self.tophbox.addWidget(self.startbutton)
        
        self.playeramt_label = QLabel('Number of players:')
        self.playeramt_label.setFixedWidth(125)
        
        self.playeramount = QComboBox()
        self.playeramount.setStyleSheet('color: rgb(0, 0, 0)')
        self.playeramount.setFixedWidth(50)
        self.playeramount.addItems([str(i) for i in range(2, 13)])
        self.playeramount.setCurrentIndex(2)
        self.playeramount.setMaxVisibleItems(11)
        self.playeramount.currentTextChanged.connect(self.form_player_entries)
        
        self.score_label = QLabel('Score limit:')
        self.score_label.setFixedWidth(65)
        
        self.score_limit = QLineEdit()
        self.score_limit.setMaximumWidth(40)
        self.score_limit.setPalette(QPalette(Qt.white))
        self.score_limit.setText('16')
        
        self.mode_label = QLabel('Game Mode:')
        self.mode_label.setFixedWidth(85)
        
        self.mode_select = QComboBox()
        self.mode_select.addItems(['Deal-1', 'Deal-4'])
        self.mode_select.setPalette(QPalette(Qt.white))
        self.mode_select.setFixedWidth(100)
        self.mode_select.currentTextChanged.connect(self.update_playeramount)
            
        self.autofill_button = Button(self, 'Auto Fill')
        self.autofill_button.clicked.connect(self.auto_fill)
        self.clear_button = Button(self, 'Clear All')
        self.clear_button.clicked.connect(self.clear_all)
        
        self.player_entries = QVBoxLayout()
        
        self.spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        
        self.hbox.addWidget(self.playeramt_label)
        self.hbox.addWidget(self.playeramount)
        self.hbox.addWidget(self.score_label)
        self.hbox.addWidget(self.score_limit)
        self.hbox.addWidget(self.mode_label)
        self.hbox.addWidget(self.mode_select)
        self.hbox.addWidget(self.autofill_button)
        self.hbox.addWidget(self.clear_button)
        
        self.vbox.addLayout(self.tophbox)
        self.vbox.addLayout(self.hbox)
        self.vbox.addLayout(self.player_entries)
        self.vbox.addItem(self.spacer)
        
        self.setLayout(self.vbox)
        
        self.form_player_entries() 


    def form_player_entries(self):
        amt = self.playeramount.currentIndex() + 2  #desired amount of player entries
        curr = self.player_entries.count()          #current amount of player entries
        dif = amt - self.player_entries.count()     #difference between desired and current entries
        
        if dif < 0:                                 #if too many entries currently 
            for i in range(curr-1, amt-1, -1):      #remove starting from last entry
                rm = self.player_entries.itemAt(i).widget()
                self.player_entries.removeWidget(rm)
                rm.setParent(None)
                
        
        else:                                       #if too few entries, add until desired amount reached
            for i in range(dif):
                new_entry = PlayerInfoField(self, self.player_entries.count())
                new_entry.name_field.textChanged.connect(self.check_filled)
                self.player_entries.addWidget(new_entry)
         
        self.check_filled()       
    
    
    def check_filled(self): #Enables start button when player fields are correctly filled
        ready = True
        
        for i in range(self.player_entries.count()):
            entry = self.player_entries.itemAt(i).widget()
            if entry.name_field.text() == '':
                ready = False
                break
            
        if ready:
            self.startbutton.setEnabled(True)
        else:
            self.startbutton.setEnabled(False)
            
                
    def auto_fill(self): #Generates fills the rest of the form automatically
        for i in range(self.player_entries.count()):
            entry = self.player_entries.itemAt(i).widget()
            if entry.name_field.text() == '':
                entry.generate_name()
                entry.AItoggle.setChecked(True)
                
    def clear_all(self):
        for i in range(self.player_entries.count()):
            entry = self.player_entries.itemAt(i).widget()
            entry.name_field.clear()
            entry.AItoggle.setChecked(False)
            
    def update_playeramount(self, mode):
        ind = self.playeramount.currentIndex()
        if mode == 'Deal-1': #Limit max players to 12
            self.playeramount.clear()
            self.playeramount.addItems([str(i) for i in range(2, 13)])
            self.playeramount.setCurrentIndex(ind)
            
        if mode == 'Deal-4': #Limit max players to 4
            self.playeramount.clear()
            self.playeramount.addItems([str(i) for i in range(2, 5)])
            self.playeramount.setCurrentIndex(min(2, ind))
            
        self.check_filled()
            
                
    def extract_info_and_init_game(self): #Creates a game object based on the info 
        pointlimit = int(self.score_limit.text())
        dealmode = self.mode_select.currentIndex()
        game = Game(pointlimit, dealmode)
        
        for i in range(self.player_entries.count()):
            entry = self.player_entries.itemAt(i).widget()
            name = entry.name_field.text()
            if entry.AItoggle.isChecked():
                difficulty = entry.AIdifficulty.currentIndex()
                game.add_player(name, difficulty)
            else:
                game.add_player(name, 5)
            
        return game
Ejemplo n.º 6
0
class SearchTheInternet(QWidget):

    changed_signal = pyqtSignal()

    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.sa = QScrollArea(self)
        self.lw = QWidget(self)
        self.l = QVBoxLayout(self.lw)
        self.sa.setWidget(self.lw), self.sa.setWidgetResizable(True)
        self.gl = gl = QVBoxLayout(self)
        self.la = QLabel(_(
            'Add new locations to search for books or authors using the "Search the internet" feature'
            ' of the Content server. The URLs should contain {author} which will be'
            ' replaced by the author name and, for book URLs, {title} which will'
            ' be replaced by the book title.'))
        self.la.setWordWrap(True)
        gl.addWidget(self.la)

        self.h = QHBoxLayout()
        gl.addLayout(self.h)
        self.add_url_button = b = QPushButton(QIcon(I('plus.png')), _('&Add URL'))
        b.clicked.connect(self.add_url)
        self.h.addWidget(b)
        self.export_button = b = QPushButton(_('Export URLs'))
        b.clicked.connect(self.export_urls)
        self.h.addWidget(b)
        self.import_button = b = QPushButton(_('Import URLs'))
        b.clicked.connect(self.import_urls)
        self.h.addWidget(b)
        self.clear_button = b = QPushButton(_('Clear'))
        b.clicked.connect(self.clear)
        self.h.addWidget(b)

        self.h.addStretch(10)
        gl.addWidget(self.sa, stretch=10)
        self.items = []

    def genesis(self):
        self.current_urls = search_the_net_urls() or []

    @property
    def current_urls(self):
        return [item.as_dict for item in self.items if not item.is_empty]

    def append_item(self, item_as_dict):
        self.items.append(URLItem(item_as_dict, self))
        self.l.addWidget(self.items[-1])

    def clear(self):
        [(self.l.removeWidget(w), w.setParent(None), w.deleteLater()) for w in self.items]
        self.items = []
        self.changed_signal.emit()

    @current_urls.setter
    def current_urls(self, val):
        self.clear()
        for entry in val:
            self.append_item(entry)

    def add_url(self):
        self.items.append(URLItem(None, self))
        self.l.addWidget(self.items[-1])
        QTimer.singleShot(100, self.scroll_to_bottom)

    def scroll_to_bottom(self):
        sb = self.sa.verticalScrollBar()
        if sb:
            sb.setValue(sb.maximum())
        self.items[-1].name_widget.setFocus(Qt.OtherFocusReason)

    @property
    def serialized_urls(self):
        return json.dumps(self.current_urls, indent=2)

    def commit(self):
        for item in self.items:
            if not item.validate():
                return False
        cu = self.current_urls
        if cu:
            with lopen(search_the_net_urls.path, 'wb') as f:
                f.write(self.serialized_urls)
        else:
            try:
                os.remove(search_the_net_urls.path)
            except EnvironmentError as err:
                if err.errno != errno.ENOENT:
                    raise
        return True

    def export_urls(self):
        path = choose_save_file(
            self, 'search-net-urls', _('Choose URLs file'),
            filters=[(_('URL files'), ['json'])], initial_filename='search-urls.json')
        if path:
            with lopen(path, 'wb') as f:
                f.write(self.serialized_urls)

    def import_urls(self):
        paths = choose_files(self, 'search-net-urls', _('Choose URLs file'),
            filters=[(_('URL files'), ['json'])], all_files=False, select_only_single_file=True)
        if paths:
            with lopen(paths[0], 'rb') as f:
                items = json.loads(f.read())
                [self.append_item(x) for x in items]
                self.changed_signal.emit()