Exemple #1
0
    def __init__(self, parent=None):
        super(WorldListWidget, self).__init__(parent, f=Qt.Tool)
        self.setWindowTitle("World List")
        self.setWindowModality(Qt.NonModal)
        load_ui('world_list.ui', baseinstance=self)

        self.worldView = None
        self.chunkLoader = None

        self.errorWidget = None
        self.blankWidget = QtGui.QWidget()
        self.stackedWidget.addWidget(self.blankWidget)

        self.editButton.clicked.connect(self.editClicked)
        self.cancelButton.clicked.connect(self.reject)
        self.showListAgainInput.setEnabled(False)

        self.viewButton.clicked.connect(self.viewClicked)
        self.viewButton.setEnabled(False)

        self.openWorldButton.clicked.connect(self.openWorldClicked)

        self.repairButton.clicked.connect(self.repairClicked)
        self.repairButton.setEnabled(False)
        self.backupButton.clicked.connect(self.backupClicked)
        self.backupButton.setEnabled(False)
        self.configureButton.clicked.connect(self.configureClicked)

        centerWidgetInScreen(self, 0.75)

        delegate = WorldListItemDelegate()
        self.worldListView.setItemDelegate(delegate)
        delegate.setParent(
            self.worldListView
        )  # PYSIDE-152: get the view widget to the drawPrimitive call

        self.worldListView.clicked.connect(self.worldListItemClicked)
        self.worldListView.doubleClicked.connect(
            self.worldListItemDoubleClicked)

        self.loadTimer = LoaderTimer(interval=0, timeout=self.loadTimerFired)
        self.loadTimer.start()

        self._updateInstalls()

        self.savesFolderComboBox.currentIndexChanged.connect(self.reloadList)
        self.minecraftInstallBox.currentIndexChanged.connect(
            minecraftinstall.currentInstallOption.setValue)
        self.minecraftVersionBox.currentIndexChanged[str].connect(
            minecraftinstall.currentVersionOption.setValue)
        self.resourcePackBox.currentIndexChanged.connect(
            self.resourcePackChanged)
        self.worldListModel = None
        self.reloadList()
        self.reloadRecentWorlds()
Exemple #2
0
def showProgress(text, iter, cancel=False):
    """
    Show a progress dialog for the given task. The task should be an iterable, yielding progress info as
    (current, max) or (current, max, statusString) tuples. Return the last value yielded by the task.
    :param text:
    :type text:
    :param iter:
    :type iter:
    :param cancel:
    :type cancel:
    :return:
    :rtype:
    """
    from mcedit2 import editorapp

    dialog = QtGui.QProgressDialog(editorapp.MCEditApp.app.mainWindow)
    dialog.setWindowTitle(text)
    dialog.setWindowModality(Qt.WindowModal)
    dialog.show()
    progress = None
    LoaderTimer.stopAll()

    for progress in iter:
        if isinstance(progress, basestring):
            max = current = 0
            status = progress
        elif isinstance(progress, (tuple, list)):
            if len(progress) > 2:
                current, max, status = progress[:3]
            else:
                current, max = progress
                status = ""
        else:
            current = max = 1
            status = ""

        dialog.setValue(current)
        dialog.setMaximum(max)
        dialog.setLabelText(status)
        QtGui.QApplication.processEvents()
        if dialog.wasCanceled():
            return False

    LoaderTimer.startAll()

    dialog.close()
    return progress
Exemple #3
0
    def __init__(self, parent=None, f=0):
        super(WorldListWidget, self).__init__(parent, f)
        self.setWindowTitle("World List")

        self.saveFileDir = None
        self.worldView = None
        self.chunkLoader = None

        self.errorWidget = QtGui.QWidget()

        load_ui('world_list.ui', baseinstance=self)

        self.setLayout(Row(self))

        self.editButton.clicked.connect(self.editClicked)
        self.cancelButton.clicked.connect(self.reject)
        self.showListAgainInput.setEnabled(False)

        self.viewButton.clicked.connect(self.viewClicked)
        self.viewButton.setEnabled(False)

        self.repairButton.clicked.connect(self.repairClicked)
        self.repairButton.setEnabled(False)
        self.backupButton.clicked.connect(self.backupClicked)
        self.backupButton.setEnabled(False)
        self.configureButton.clicked.connect(self.configureClicked)

        screen = QtGui.QApplication.desktop().availableGeometry()
        w = screen.width()
        h = screen.height()
        margin = 0.125
        r = QtCore.QRect(screen.x() + margin * w,
                         screen.y() + margin * h, w - w * 2 * margin,
                         h - h * 2 * margin)

        self.setGeometry(r)

        self.loadTimer = LoaderTimer(interval=0, timeout=self.loadTimerFired)
        self.loadTimer.start()

        for install in minecraftinstall.listInstalls():
            self.minecraftInstallBox.addItem(install.name)
        self.minecraftInstallBox.setCurrentIndex(
            minecraftinstall.selectedInstallIndex())
        self._updateVersionsAndResourcePacks()
        self.reloadList()
Exemple #4
0
    def __init__(self, parent=None, f=0):
        super(WorldListWidget, self).__init__(parent, f)
        self.setWindowTitle("World List")

        self.saveFileDir = None
        self.worldView = None
        self.chunkLoader = None

        self.errorWidget = QtGui.QWidget()

        load_ui('world_list.ui', baseinstance=self)

        self.setLayout(Row(self))

        self.editButton.clicked.connect(self.editClicked)
        self.cancelButton.clicked.connect(self.reject)
        self.showListAgainInput.setEnabled(False)

        self.viewButton.clicked.connect(self.viewClicked)
        self.viewButton.setEnabled(False)

        self.openWorldButton.clicked.connect(self.openWorldClicked)

        self.repairButton.clicked.connect(self.repairClicked)
        self.repairButton.setEnabled(False)
        self.backupButton.clicked.connect(self.backupClicked)
        self.backupButton.setEnabled(False)
        self.configureButton.clicked.connect(self.configureClicked)

        centerWidgetInScreen(self, 0.75)

        self.loadTimer = LoaderTimer(interval=0, timeout=self.loadTimerFired)
        self.loadTimer.start()

        for install in minecraftinstall.listInstalls():
            self.minecraftInstallBox.addItem(install.name)
        self.minecraftInstallBox.setCurrentIndex(
            minecraftinstall.selectedInstallIndex())
        self._updateVersionsAndResourcePacks()
        self.reloadList()
def showProgress(text, iter, cancel=False):
    """
    Show a progress dialog for the given task. The task should be an iterable, yielding progress info as
    (current, max) or (current, max, statusString) tuples. Return the last value yielded by the task.
    :param text:
    :type text:
    :param iter:
    :type iter:
    :param cancel:
    :type cancel:
    :return:
    :rtype:
    """
    progress = None
    i = 0
    start = time.time()
    with LoaderTimer.stopCtx():
        for progress in iter:
            if time.time() - start > timeBeforeDialog:
                break
        else:
            return progress

        dialog = QtGui.QProgressDialog(QtGui.qApp.mainWindow)
        dialog.setWindowTitle(text)
        dialog.setWindowModality(Qt.WindowModal)
        dialog.show()


        for progress in iter:
            if isinstance(progress, basestring):
                max = current = 0
                status = progress
            elif isinstance(progress, tuple):
                if len(progress) > 2:
                    current, max, status = progress[:3]
                else:
                    current, max = progress
                    status = ""
            else:
                current = max = 1
                status = ""

            dialog.setValue(current)
            dialog.setMaximum(max)
            dialog.setLabelText(status)
            QtGui.QApplication.processEvents()
            if dialog.wasCanceled():
                return False

        dialog.close()
        return progress
Exemple #6
0
def showProgress(text, iter, cancel=False):
    """
    Show a progress dialog for the given task. The task should be an iterable, yielding progress info as
    (current, max) or (current, max, statusString) tuples. Return the last value yielded by the task.
    :param text:
    :type text:
    :param iter:
    :type iter:
    :param cancel:
    :type cancel:
    :return:
    :rtype:
    """
    progress = None
    i = 0
    start = time.time()
    with LoaderTimer.stopCtx():
        for progress in iter:
            if time.time() - start > timeBeforeDialog:
                break
        else:
            return progress

        dialog = QtGui.QProgressDialog(QtGui.qApp.mainWindow)
        dialog.setWindowTitle(text)
        dialog.setWindowModality(Qt.WindowModal)
        dialog.show()

        for progress in iter:
            if isinstance(progress, basestring):
                max = current = 0
                status = progress
            elif isinstance(progress, tuple):
                if len(progress) > 2:
                    current, max, status = progress[:3]
                else:
                    current, max = progress
                    status = ""
            else:
                current = max = 1
                status = ""

            dialog.setValue(current)
            dialog.setMaximum(max)
            dialog.setLabelText(status)
            QtGui.QApplication.processEvents()
            if dialog.wasCanceled():
                return False

        dialog.close()
        return progress
Exemple #7
0
    def __init__(self, parent=None):
        super(WorldListWidget, self).__init__(parent, f=Qt.Tool)
        self.setWindowTitle("World List")
        self.setWindowModality(Qt.NonModal)
        self.setupUi(self)

        self.worldView = None
        self.chunkLoader = None

        self.errorWidget = None
        self.blankWidget = QtGui.QWidget()
        self.stackedWidget.addWidget(self.blankWidget)

        self.editButton.clicked.connect(self.editClicked)
        self.cancelButton.clicked.connect(self.reject)
        self.showListAgainInput.setEnabled(False)

        self.viewButton.clicked.connect(self.viewClicked)

        self.openWorldButton.clicked.connect(self.openWorldClicked)

        self.repairButton.clicked.connect(self.repairClicked)
        self.repairButton.setEnabled(False)
        self.backupButton.clicked.connect(self.backupClicked)
        self.backupButton.setEnabled(False)
        self.configureButton.clicked.connect(self.configureClicked)

        self.chooseSavesFolderButton.clicked.connect(self.chooseSavesFolder)

        centerWidgetInScreen(self, 0.75)

        delegate = WorldListItemDelegate()
        self.worldListView.setItemDelegate(delegate)
        delegate.setParent(self.worldListView)  # PYSIDE-152: get the view widget to the drawPrimitive call

        self.worldListView.clicked.connect(self.worldListItemClicked)
        self.worldListView.doubleClicked.connect(self.worldListItemDoubleClicked)

        self.loadTimer = LoaderTimer(interval=0, timeout=self.loadTimerFired)
        self.loadTimer.start()

        self._updateInstalls()

        self.savesFolderComboBox.currentIndexChanged.connect(self.reloadList)
        self.minecraftInstallBox.currentIndexChanged.connect(minecraftinstall.currentInstallOption.setValue)
        self.minecraftVersionBox.currentIndexChanged[str].connect(minecraftinstall.currentVersionOption.setValue)
        self.resourcePackBox.currentIndexChanged.connect(self.resourcePackChanged)
        self.worldListModel = None
        self.reloadList()
        self.reloadRecentWorlds()
Exemple #8
0
    def __init__(self, parent=None, f=0):
        super(WorldListWidget, self).__init__(parent, f)
        self.setWindowTitle("World List")
        load_ui('world_list.ui', baseinstance=self)

        self.worldView = None
        self.chunkLoader = None

        self.errorWidget = None
        self.blankWidget = QtGui.QWidget()
        self.stackedWidget.addWidget(self.blankWidget)

        self.editButton.clicked.connect(self.editClicked)
        self.cancelButton.clicked.connect(self.reject)
        self.showListAgainInput.setEnabled(False)

        self.viewButton.clicked.connect(self.viewClicked)
        self.viewButton.setEnabled(False)

        self.openWorldButton.clicked.connect(self.openWorldClicked)

        self.repairButton.clicked.connect(self.repairClicked)
        self.repairButton.setEnabled(False)
        self.backupButton.clicked.connect(self.backupClicked)
        self.backupButton.setEnabled(False)
        self.configureButton.clicked.connect(self.configureClicked)

        centerWidgetInScreen(self, 0.75)

        delegate = WorldListItemDelegate()
        self.worldListView.setItemDelegate(delegate)
        delegate.setParent(self.worldListView)  # PYSIDE-152: get the view widget to the drawPrimitive call

        self.worldListView.clicked.connect(self.worldListItemClicked)
        self.worldListView.doubleClicked.connect(self.worldListItemDoubleClicked)

        self.loadTimer = LoaderTimer(interval=0, timeout=self.loadTimerFired)
        self.loadTimer.start()

        self._updateInstalls()

        self.savesFolderComboBox.currentIndexChanged.connect(self.reloadList)

        self.worldListModel = None
        self.reloadList()
        self.reloadRecentWorlds()
Exemple #9
0
    def __init__(self, parent=None):
        super(WorldListWidget, self).__init__(parent, f=Qt.Tool)
        self.setWindowTitle("World List")
        self.setWindowModality(Qt.NonModal)
        self.setupUi(self)

        self.worldView = None
        self.chunkLoader = None

        self.errorWidget = None
        self.blankWidget = QtGui.QWidget()
        self.stackedWidget.addWidget(self.blankWidget)

        self.editButton.clicked.connect(self.editClicked)
        self.cancelButton.clicked.connect(self.reject)
        self.showListAgainInput.setEnabled(False)

        self.viewButton.clicked.connect(self.viewClicked)

        self.openWorldButton.clicked.connect(self.openWorldClicked)

        self.repairButton.clicked.connect(self.repairClicked)
        self.repairButton.setEnabled(False)
        self.backupButton.clicked.connect(self.backupClicked)
        self.backupButton.setEnabled(False)
        self.configureButton.clicked.connect(self.configureClicked)

        self.chooseSavesFolderButton.clicked.connect(self.chooseSavesFolder)

        centerWidgetInScreen(self, 0.75)

        delegate = WorldListItemDelegate()
        self.worldListView.setItemDelegate(delegate)
        delegate.setParent(self.worldListView)  # PYSIDE-152: get the view widget to the drawPrimitive call

        self.worldListView.clicked.connect(self.worldListItemClicked)
        self.worldListView.doubleClicked.connect(self.worldListItemDoubleClicked)

        self.loadTimer = LoaderTimer(interval=0, timeout=self.loadTimerFired)
        self.loadTimer.start()

        self._updateInstalls()

        try:
            savesFolders = WorldListSettings.allSavesFolders.value()
            for filename in savesFolders:
                if not os.path.isdir(filename):
                    continue
                dirname, basename = os.path.split(filename)
                displayName = os.sep.join(dirname.split(os.sep)[-2:] + [basename])
                self.savesFolderComboBox.addItem(displayName, filename)
        except (ValueError, KeyError) as e:
            log.warn("Failed to load saves folder list.")

        currentFolder = WorldListSettings.currentSavesFolder.value()
        if os.path.isdir(currentFolder):
            index = self.savesFolderComboBox.findData(currentFolder)
            if index != -1:
                self.savesFolderComboBox.setCurrentIndex(index)

        self.savesFolderComboBox.currentIndexChanged.connect(self.savesFolderChanged)
        self.minecraftInstallBox.currentIndexChanged.connect(self.currentInstallChanged)
        self.minecraftVersionBox.currentIndexChanged[str].connect(minecraftinstall.currentVersionOption.setValue)
        self.resourcePackBox.currentIndexChanged.connect(self.resourcePackChanged)
        self.worldListModel = None
        self.reloadList()
        self.reloadRecentWorlds()
Exemple #10
0
class WorldListWidget(QtGui.QDialog, Ui_worldList):
    def __init__(self, parent=None):
        super(WorldListWidget, self).__init__(parent, f=Qt.Tool)
        self.setWindowTitle("World List")
        self.setWindowModality(Qt.NonModal)
        self.setupUi(self)

        self.worldView = None
        self.chunkLoader = None

        self.errorWidget = None
        self.blankWidget = QtGui.QWidget()
        self.stackedWidget.addWidget(self.blankWidget)

        self.editButton.clicked.connect(self.editClicked)
        self.cancelButton.clicked.connect(self.reject)
        self.showListAgainInput.setEnabled(False)

        self.viewButton.clicked.connect(self.viewClicked)

        self.openWorldButton.clicked.connect(self.openWorldClicked)

        self.repairButton.clicked.connect(self.repairClicked)
        self.repairButton.setEnabled(False)
        self.backupButton.clicked.connect(self.backupClicked)
        self.backupButton.setEnabled(False)
        self.configureButton.clicked.connect(self.configureClicked)

        self.chooseSavesFolderButton.clicked.connect(self.chooseSavesFolder)

        centerWidgetInScreen(self, 0.75)

        delegate = WorldListItemDelegate()
        self.worldListView.setItemDelegate(delegate)
        delegate.setParent(self.worldListView)  # PYSIDE-152: get the view widget to the drawPrimitive call

        self.worldListView.clicked.connect(self.worldListItemClicked)
        self.worldListView.doubleClicked.connect(self.worldListItemDoubleClicked)

        self.loadTimer = LoaderTimer(interval=0, timeout=self.loadTimerFired)
        self.loadTimer.start()

        self._updateInstalls()

        try:
            savesFolders = WorldListSettings.allSavesFolders.value()
            for filename in savesFolders:
                if not os.path.isdir(filename):
                    continue
                dirname, basename = os.path.split(filename)
                displayName = os.sep.join(dirname.split(os.sep)[-2:] + [basename])
                self.savesFolderComboBox.addItem(displayName, filename)
        except (ValueError, KeyError) as e:
            log.warn("Failed to load saves folder list.")

        currentFolder = WorldListSettings.currentSavesFolder.value()
        if os.path.isdir(currentFolder):
            index = self.savesFolderComboBox.findData(currentFolder)
            if index != -1:
                self.savesFolderComboBox.setCurrentIndex(index)

        self.savesFolderComboBox.currentIndexChanged.connect(self.savesFolderChanged)
        self.minecraftInstallBox.currentIndexChanged.connect(self.currentInstallChanged)
        self.minecraftVersionBox.currentIndexChanged[str].connect(minecraftinstall.currentVersionOption.setValue)
        self.resourcePackBox.currentIndexChanged.connect(self.resourcePackChanged)
        self.worldListModel = None
        self.reloadList()
        self.reloadRecentWorlds()

    def currentInstallChanged(self, index):
        path = self.minecraftInstallBox.itemData(index)
        minecraftinstall.currentInstallOption.setValue(path)

    def resourcePackChanged(self, index):
        if index == 0:
            minecraftinstall.currentResourcePackOption.setValue("")
        else:
            minecraftinstall.currentResourcePackOption.setValue(self.resourcePackBox.currentText())

    def _updateInstalls(self):
        self.minecraftInstallBox.clear()

        for install in minecraftinstall.GetInstalls().installs:
            self.minecraftInstallBox.addItem(install.name, install.path)
            for saveDir in install.getSaveDirs():
                self.savesFolderComboBox.addItem(install.name + os.sep + os.path.basename(saveDir), saveDir)

        for instance in minecraftinstall.GetInstalls().instances:
            saveDir = instance.saveFileDir
            self.savesFolderComboBox.addItem(instance.name + os.sep + os.path.basename(saveDir), saveDir)

        path = minecraftinstall.GetInstalls().selectedInstallPath()
        index = self.minecraftInstallBox.findData(path)
        self.minecraftInstallBox.setCurrentIndex(index)

        self._updateVersionsAndResourcePacks()

    def _updateVersionsAndResourcePacks(self):
        self.minecraftVersionBox.clear()
        self.resourcePackBox.clear()
        self.resourcePackBox.addItem(self.tr("(No resource pack)"))

        path = minecraftinstall.currentInstallOption.value()
        install = minecraftinstall.GetInstalls().getInstall(path)

        if install:
            for version in sorted(install.versions, reverse=True):
                self.minecraftVersionBox.addItem(version)

            for resourcePack in sorted(install.resourcePacks):
                self.resourcePackBox.addItem(resourcePack)

    def chooseSavesFolder(self):
        startingDir = WorldListSettings.lastChosenSavesFolder.value()
        if startingDir == '' or not os.path.isdir(startingDir):
            startingDir = os.path.expanduser(b"~")

        filename = QtGui.QFileDialog.getExistingDirectory(
            self, self.tr("Choose Saves Folder"), startingDir
        )

        if filename:
            log.info("Adding saves folder %s", filename)

            savesFolders = WorldListSettings.allSavesFolders.value()
            savesFolders.append(filename)
            WorldListSettings.allSavesFolders.setValue(savesFolders)

            dirname, basename = os.path.split(filename)
            displayName = os.sep.join(dirname.split(os.sep)[-2:] + [basename])
            WorldListSettings.lastChosenSavesFolder.setValue(filename)
            self.savesFolderComboBox.addItem(displayName, filename)
            self.savesFolderComboBox.setCurrentIndex(self.savesFolderComboBox.count()-1)

    def reloadRecentWorlds(self):
        recentWorlds = RecentFilesSetting.value()
        self.recentWorldsMenu = QtGui.QMenu()

        def _triggered(f):
            def triggered():
                self.accept()
                self.editWorldClicked.emit(f)
            return triggered
        dead = []
        for filename in recentWorlds:
            if not os.path.exists(filename):
                dead.append(filename)
                continue
            try:
                displayName, lastPlayed, versionInfo = WorldEditor.getWorldInfo(filename)
                action = self.recentWorldsMenu.addAction(displayName)
                action._editWorld = _triggered(filename)
                action.triggered.connect(action._editWorld)
            except EnvironmentError as e:
                log.exception("Failed to load world info")

        if len(dead):
            for f in dead:
                recentWorlds.remove(f)
            RecentFilesSetting.setValue(recentWorlds)

        self.recentWorldsButton.setMenu(self.recentWorldsMenu)

    def savesFolderChanged(self):
        currentFolder = self.savesFolderComboBox.itemData(self.savesFolderComboBox.currentIndex())
        WorldListSettings.currentSavesFolder.setValue(currentFolder)
        
        self.reloadList()
        if len(self.worldListModel.worlds):
            self.worldListView.setFocus()
            self.worldListView.setCurrentIndex(self.worldListModel.createIndex(0, 0))
            self.showWorld(self.worldListModel.worlds[0][0])
        else:
            self.removeWorldView()

    def reloadList(self):
        try:
            saveFileDir = self.savesFolderComboBox.itemData(self.savesFolderComboBox.currentIndex())
            if saveFileDir is None:
                log.error("No item selected in savesFolderComboBox!!(?)")
                return
            if not os.path.isdir(saveFileDir):
                raise IOError(u"Could not find the Minecraft saves directory!\n\n({0} was not found or is not a directory)".format(saveFileDir))

            log.info("Scanning %s for worlds...", saveFileDir)
            potentialWorlds = os.listdir(saveFileDir)
            potentialWorlds = [os.path.join(saveFileDir, p) for p in potentialWorlds]
            worldFiles = [p for p in potentialWorlds if isLevel(AnvilWorldAdapter, p)]

            self.worldListModel = WorldListModel(worldFiles)
            self.worldListView.setModel(self.worldListModel)

        except Exception as e:
            setWidgetError(self, e, "An error occurred while scanning the saves folder.")

    def openWorldClicked(self):
        QtGui.qApp.chooseOpenWorld()

    _currentFilename = None

    def worldListItemClicked(self, index):
        filename = index.data()
        self.showWorld(filename)

    def worldListItemDoubleClicked(self, index):
        row = index.row()
        self.accept()
        self.editWorldClicked.emit(self.worldListModel.worlds[row][0])

    def showWorld(self, filename):
        if filename == self._currentFilename:
            return
        self._currentFilename = filename

        self.removeWorldView()

        try:
            worldEditor = worldeditor.WorldEditor(filename, readonly=True)

        except (EnvironmentError, LevelFormatError, zipfile.BadZipfile) as e:
            self.errorWidget = QtGui.QWidget()
            setWidgetError(self.errorWidget, e, "An error occurred while reading the world %s." % filename)
            self.stackedWidget.addWidget(self.errorWidget)
            self.stackedWidget.setCurrentWidget(self.errorWidget)

        else:

            dim = worldEditor.getDimension()
            self.setWorldView(MinimapWorldView(dim))
            self.chunkLoader = ChunkLoader(dim)
            self.chunkLoader.addClient(self.worldView)
            self.chunkLoader.chunkCompleted.connect(self.worldView.update)

            try:
                try:
                    player = worldEditor.getPlayer()
                    log.info("Centering on single-player player.")
                except PlayerNotFound:
                    try:
                        center = worldEditor.getWorldMetadata().Spawn
                        log.info("Centering on spawn position.")
                    except AttributeError:
                        log.info("Centering on world center")
                        center = dim.bounds.origin + (dim.bounds.size * 0.5)
                else:
                    if player.dimName == dim.dimName:
                        center = Vector(*player.Position)
                        self.worldView.centerOnPoint(center)
                    else:
                        center = dim.bounds.origin + (dim.bounds.size * 0.5)

                self.worldView.centerOnPoint(center)
            except Exception as e:
                log.exception("Error while centering view in world list: %s", e)

            log.info("Switched world view")

    def setWorldView(self, worldView):
        if self.worldView:
            self.removeWorldView()
        self.worldView = worldView
        self.stackedWidget.addWidget(worldView)
        self.stackedWidget.setCurrentWidget(worldView)

    def removeWorldView(self):
        self.stackedWidget.setCurrentWidget(self.blankWidget)
        QtGui.qApp.processEvents()  # force repaint of stackedWidget to hide old error widget
        if self.worldView:
            log.info("Removing view from WorldListWidget")
            self.worldView.dealloc()
            self.stackedWidget.removeWidget(self.worldView)
            self.worldView.setParent(None)
            self.worldView = None
        if self.errorWidget:
            self.stackedWidget.removeWidget(self.errorWidget)
            self.errorWidget = None

        self.chunkLoader = None

        # ensure WorldView gets freed now and not later
        # if it is freed later, it will call makeCurrent and ruin another view's render
        import gc; gc.collect()

    def hide(self):
        self.removeWorldView()
        super(WorldListWidget, self).hide()

    def close(self):
        self.removeWorldView()
        super(WorldListWidget, self).close()

    def reject(self):
        self.removeWorldView()
        super(WorldListWidget, self).reject()

    def showEvent(self, event):
        if self.worldListModel and len(self.worldListModel.worlds):
            self.worldListView.setFocus()
            self.worldListView.setCurrentIndex(self.worldListModel.createIndex(0, 0))
            self.showWorld(self.worldListModel.worlds[0][0])

        self.reloadRecentWorlds()

    @profiler.function("worldListLoadTimer")
    def loadTimerFired(self):
        if not self.isVisible():
            self.loadTimer.setInterval(1000)
            return

        if self.chunkLoader:
            try:
                self.chunkLoader.next()
                self.loadTimer.setInterval(0)
            except StopIteration:
                self.loadTimer.setInterval(1000)
        else:
            self.loadTimer.setInterval(1000)

    @property
    def selectedWorldIndex(self):
        indexes = self.worldListView.selectedIndexes()
        if len(indexes):
            return indexes[0]

    editWorldClicked = QtCore.Signal(unicode)
    viewWorldClicked = QtCore.Signal(unicode)
    repairWorldClicked = QtCore.Signal(unicode)
    backupWorldClicked = QtCore.Signal(unicode)

    def editClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.editWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def viewClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.viewWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def repairClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.repairWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def backupClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.backupWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def configureClicked(self):
        installsWidget = MinecraftInstallsDialog()
        installsWidget.exec_()
        self._updateInstalls()
Exemple #11
0
    def __init__(self, argv, DEBUG=False):
        super(MCEditApp, self).__init__(argv)
        self.DEBUG = DEBUG
        MCEditApp.app = self

        minecraftinstall.GetInstalls().ensureValidInstall()
        self.ensureSingle()

        self.commandLineWorlds = []
        self.parseArgs(argv)

        log.warn("UserFilesDirectory: %s", getUserFilesDirectory())

        # --- Necessities ---

        translator = QtCore.QTranslator()
        translator.load(resourcePath('mcedit2/i18n/en_US.ts'))
        self.installTranslator(translator)

        self.setOrganizationName("MCEdit")
        self.setOrganizationDomain("mcedit.net")
        self.setApplicationName("MCEdit")
        self.setWindowIcon(
            QtGui.QIcon(resourcePath("mcedit2/assets/mcedit2/mcediticon.png")))
        styleSheet = file(resourcePath("mcedit2/styles/mcedit2.qcss")).read()
        self.setStyleSheet(styleSheet)

        # --- Main Window ---

        self.mainWindow = mainWindow = MCEditMainWindow()

        self.undoGroup = QtGui.QUndoGroup()

        self.tabWidget = self.mainWindow.tabWidget
        self.tabWidget.tabCloseRequested.connect(self.tabCloseRequested)
        self.tabWidget.currentChanged.connect(self.tabChanged)

        # --- Sessions ---

        self._currentSession = None
        self.sessions = []
        self.sessionDockWidgets = []
        self.sessionChanged.connect(self.sessionDidChange)

        # --- Panel Widgets ---

        self.undoView = QtGui.QUndoView(self.undoGroup)
        self.undoDockWidget = QtGui.QDockWidget("History",
                                                mainWindow,
                                                objectName="HistoryWidget")
        self.undoDockWidget.setWidget(self.undoView)
        mainWindow.addDockWidget(Qt.RightDockWidgetArea, self.undoDockWidget)
        mainWindow.panelsToolBar.addAction(
            self.undoDockWidget.toggleViewAction())
        self.undoDockWidget.close()

        self.logViewWidget = LogViewFrame(mainWindow)
        self.logViewDockWidget = QtGui.QDockWidget("Error Log",
                                                   mainWindow,
                                                   objectName="ErrorsWidget")
        self.logViewDockWidget.setWidget(self.logViewWidget)
        mainWindow.addDockWidget(Qt.BottomDockWidgetArea,
                                 self.logViewDockWidget)
        mainWindow.panelsToolBar.addAction(
            self.logViewDockWidget.toggleViewAction())
        self.logViewDockWidget.close()

        self.libraryView = LibraryWidget()
        self.libraryDockWidget = QtGui.QDockWidget("Library",
                                                   mainWindow,
                                                   objectName="LibraryWidget")
        self.libraryDockWidget.setWidget(self.libraryView)
        mainWindow.addDockWidget(Qt.RightDockWidgetArea,
                                 self.libraryDockWidget)
        mainWindow.panelsToolBar.addAction(
            self.libraryDockWidget.toggleViewAction())
        self.libraryDockWidget.close()

        self.libraryView.doubleClicked.connect(self.libraryItemDoubleClicked)

        self.globalPanels = [
            self.undoDockWidget, self.logViewDockWidget, self.libraryDockWidget
        ]

        # --- Debug Widgets ---

        if DEBUG:
            debugMenu = self.createDebugMenu()

            self.debugObjectInspector = ObjectInspector(mainWindow)
            self.inspectorDockWidget = QtGui.QDockWidget(
                "Inspector", mainWindow, objectName="InspectorWidget")
            self.inspectorDockWidget.setWidget(self.debugObjectInspector)
            mainWindow.addDockWidget(Qt.RightDockWidgetArea,
                                     self.inspectorDockWidget)
            debugMenu.addAction(self.inspectorDockWidget.toggleViewAction())
            self.inspectorDockWidget.close()

            self.profileView = ProfilerWidget()
            profileDockWidget = QtGui.QDockWidget("Profiler",
                                                  mainWindow,
                                                  objectName="ProfilerWidget")
            profileDockWidget.setWidget(self.profileView)
            mainWindow.addDockWidget(Qt.RightDockWidgetArea, profileDockWidget)
            debugMenu.addAction(profileDockWidget.toggleViewAction())
            profileDockWidget.close()

            self.textureAtlasView = QtGui.QLabel()
            self.textureAtlasView.setScaledContents(True)
            self.textureAtlasDockWidget = QtGui.QDockWidget(
                "Texture Atlas", mainWindow, objectName="TextureAtlasWidget")

            self.textureAtlasArea = QtGui.QScrollArea()
            self.textureAtlasArea.setWidget(self.textureAtlasView)
            self.textureAtlasDockWidget.setWidget(self.textureAtlasArea)
            mainWindow.addDockWidget(Qt.RightDockWidgetArea,
                                     self.textureAtlasDockWidget)
            debugMenu.addAction(self.textureAtlasDockWidget.toggleViewAction())
            self.textureAtlasDockWidget.close()

            infoTabs = QtGui.QTabWidget()

            self.cursorInfo = WorldCursorInfo()
            infoTabs.addTab(self.cursorInfo, "Cursor")

            self.viewInfo = WorldViewInfo()
            infoTabs.addTab(self.viewInfo, "View")

            self.loaderInfo = ChunkLoaderInfo()
            infoTabs.addTab(self.loaderInfo, "Loader")

            infoDockWidget = QtGui.QDockWidget("Debug Info",
                                               mainWindow,
                                               objectName="DebugInfo")
            infoDockWidget.setWidget(infoTabs)

            mainWindow.addDockWidget(Qt.BottomDockWidgetArea, infoDockWidget)
            mainWindow.tabifyDockWidget(infoDockWidget, self.logViewDockWidget)

            self.globalPanels.append(infoDockWidget)
            mainWindow.panelsToolBar.addAction(
                infoDockWidget.toggleViewAction())
            infoDockWidget.close()

        # --- Menu Actions ---

        # -- MCEdit menu --
        mainWindow.actionNew_World.triggered.connect(self.createNewWorld)
        mainWindow.actionNew_World.setShortcut(QtGui.QKeySequence.New)

        mainWindow.actionOpen_World.triggered.connect(self.chooseOpenWorld)
        mainWindow.actionOpen_World.setShortcut(QtGui.QKeySequence.Open)

        mainWindow.actionShow_World_List.triggered.connect(self.showWorldList)
        mainWindow.actionShow_World_List.setShortcut(
            QtGui.QKeySequence("Ctrl+L"))

        mainWindow.actionSave_World.triggered.connect(self.saveCurrentWorld)
        mainWindow.actionSave_World.setShortcut(QtGui.QKeySequence.Save)

        mainWindow.actionSave_World_As.triggered.connect(
            self.saveCurrentWorldAs)
        mainWindow.actionSave_World_As.setShortcut(QtGui.QKeySequence.SaveAs)

        mainWindow.actionClose_World.triggered.connect(self.closeCurrentTab)
        mainWindow.actionClose_World.setShortcut(QtGui.QKeySequence.Close)

        mainWindow.actionExit_MCEdit.triggered.connect(self.exitEditor)
        mainWindow.actionExit_MCEdit.setShortcut(QtGui.QKeySequence.Quit)

        # -- Help menu --
        mainWindow.actionAbout_MCEdit.triggered.connect(self.showAbout)
        mainWindow.actionAbout_MCEdit.setShortcut(QtGui.QKeySequence.Quit)

        # -- Window Menu --
        mainWindow.menuWindow.addAction(self.undoDockWidget.toggleViewAction())
        mainWindow.menuWindow.addAction(
            self.logViewDockWidget.toggleViewAction())
        mainWindow.menuWindow.addAction(
            self.libraryDockWidget.toggleViewAction())

        # --- World List ---

        self.worldList = WorldListWidget(mainWindow)
        self.worldList.editWorldClicked.connect(self.editWorldFromList)
        self.worldList.viewWorldClicked.connect(self.viewWorldFromList)
        self.worldList.backupWorldClicked.connect(self.backupWorldFromList)
        self.worldList.repairWorldClicked.connect(self.repairWorldFromList)

        # --- Status Bar ---

        self.positionLabel = QtGui.QLabel("xx, yy, zz", minimumWidth=100)
        self.blocktypeLabel = QtGui.QLabel("(-1:-1)minecraft:rocktonium",
                                           minimumWidth=250)
        self.blockNameLabel = QtGui.QLabel("rocktonium", minimumWidth=150)
        self.cpsLabel = QtGui.QLabel("-1 cps", minimumWidth=65)
        self.fpsLabel = QtGui.QLabel("-1 fps", minimumWidth=65)

        statusBar = mainWindow.statusBar()
        statusBar.addPermanentWidget(self.positionLabel)
        statusBar.addPermanentWidget(self.blocktypeLabel)
        statusBar.addPermanentWidget(self.blockNameLabel)
        statusBar.addPermanentWidget(self.cpsLabel)
        statusBar.addPermanentWidget(self.fpsLabel)

        # --- Load settings ---

        mainWindow.loadSettings()
        self.updateRecentFilesMenu()

        self.loadTimer = timer = LoaderTimer(self)
        timer.setInterval(0)
        timer.timeout.connect(self.loadTimerFired)
        timer.start()
        log.info("Loading timer started")

        mainWindow.showMaximized()

        QtCore.QTimer.singleShot(0, self.didFinishLaunching)
Exemple #12
0
def showProgress(text, *tasks, **kwargs):
    """
    Show a progress dialog for the given task(s). Each task should be an iterable,
    yielding progress info as (current, max) or (current, max, statusString) tuples.
    Return the last value yielded by the task.

    :param text:
    :type text:
    :param iter:
    :type iter:
    :param cancel:
    :type cancel:
    :return:
    :rtype:
    """
    progress = None
    cancel = kwargs.pop('cancel', None)
    start = time.time()
    shown = False
    with LoaderTimer.stopCtx():

        dialog = MCEProgressDialog(QtGui.qApp.mainWindow)
        if not cancel:
            dialog.setCancelButtonText(None)
        dialog.setWindowTitle(text)
        dialog.setWindowModality(Qt.WindowModal)
        log.info("Starting progress: %d tasks." % len(tasks))
        totalMaximum = len(tasks) * 100
        for i, task in enumerate(tasks):
            log.info("Task #%d", i)
            task = rescaleProgress(task, i * 100, i * 100 + 100)
            for progress in task:
                if isinstance(progress, basestring):
                    current = 0
                    maximum = 0
                    status = progress
                elif isinstance(progress, tuple):
                    if len(progress) > 2:
                        current, maximum, status = progress[:3]
                    else:
                        current, maximum = progress
                        status = ""
                else:
                    current = 0
                    maximum = 0
                    status = ""

                dialog.setValue(current)
                if maximum == 0:
                    # Task progress is indeterminate
                    dialog.setMaximum(0)
                else:
                    dialog.setMaximum(totalMaximum)
                dialog.setLabelText(status)
                if time.time() > start + timeBeforeDialog:
                    if not shown:
                        dialog.show()
                        shown = True
                    QtGui.QApplication.processEvents()

                if dialog.wasCanceled():
                    return False

        dialog.reset()
        return progress
Exemple #13
0
class WorldListWidget(QtGui.QDialog):
    def __init__(self, parent=None):
        super(WorldListWidget, self).__init__(parent, f=Qt.Tool)
        self.setWindowTitle("World List")
        self.setWindowModality(Qt.NonModal)
        load_ui('world_list.ui', baseinstance=self)

        self.worldView = None
        self.chunkLoader = None

        self.errorWidget = None
        self.blankWidget = QtGui.QWidget()
        self.stackedWidget.addWidget(self.blankWidget)

        self.editButton.clicked.connect(self.editClicked)
        self.cancelButton.clicked.connect(self.reject)
        self.showListAgainInput.setEnabled(False)

        self.viewButton.clicked.connect(self.viewClicked)
        self.viewButton.setEnabled(False)

        self.openWorldButton.clicked.connect(self.openWorldClicked)

        self.repairButton.clicked.connect(self.repairClicked)
        self.repairButton.setEnabled(False)
        self.backupButton.clicked.connect(self.backupClicked)
        self.backupButton.setEnabled(False)
        self.configureButton.clicked.connect(self.configureClicked)

        centerWidgetInScreen(self, 0.75)

        delegate = WorldListItemDelegate()
        self.worldListView.setItemDelegate(delegate)
        delegate.setParent(
            self.worldListView
        )  # PYSIDE-152: get the view widget to the drawPrimitive call

        self.worldListView.clicked.connect(self.worldListItemClicked)
        self.worldListView.doubleClicked.connect(
            self.worldListItemDoubleClicked)

        self.loadTimer = LoaderTimer(interval=0, timeout=self.loadTimerFired)
        self.loadTimer.start()

        self._updateInstalls()

        self.savesFolderComboBox.currentIndexChanged.connect(self.reloadList)
        self.minecraftInstallBox.currentIndexChanged.connect(
            minecraftinstall.currentInstallOption.setValue)
        self.minecraftVersionBox.currentIndexChanged[str].connect(
            minecraftinstall.currentVersionOption.setValue)
        self.resourcePackBox.currentIndexChanged.connect(
            self.resourcePackChanged)
        self.worldListModel = None
        self.reloadList()
        self.reloadRecentWorlds()

    def resourcePackChanged(self, index):
        if index == 0:
            minecraftinstall.currentResourcePackOption.setValue("")
        else:
            minecraftinstall.currentResourcePackOption.setValue(
                self.resourcePackBox.currentText())

    def _updateInstalls(self):
        for install in minecraftinstall.GetInstalls().installs:
            self.minecraftInstallBox.addItem(install.name)

        self.minecraftInstallBox.setCurrentIndex(
            minecraftinstall.GetInstalls().selectedInstallIndex())

        self._updateVersionsAndResourcePacks()

    def _updateVersionsAndResourcePacks(self):
        self.minecraftVersionBox.clear()
        self.resourcePackBox.clear()
        self.resourcePackBox.addItem(self.tr("(No resource pack)"))

        self.savesFolderComboBox.clear()

        if self.minecraftInstallBox.count():
            install = minecraftinstall.GetInstalls().getInstall(
                self.minecraftInstallBox.currentIndex())

            for version in sorted(install.versions, reverse=True):
                self.minecraftVersionBox.addItem(version)

            for resourcePack in sorted(install.resourcePacks):
                self.resourcePackBox.addItem(resourcePack)

            for filename in install.getSaveDirs():
                self.savesFolderComboBox.addItem(
                    os.path.basename(os.path.dirname(filename)),
                    (filename, None))

        for index, instance in enumerate(
                minecraftinstall.GetInstalls().instances):  # xxx instanceID?
            self.savesFolderComboBox.addItem(instance.name,
                                             (instance.saveFileDir, index))

    def reloadRecentWorlds(self):
        recentWorlds = RecentFilesSetting.value()
        self.recentWorldsMenu = QtGui.QMenu()

        def _triggered(f):
            def triggered():
                self.accept()
                self.editWorldClicked.emit(f)

            return triggered

        dead = []
        for filename in recentWorlds:
            if not os.path.exists(filename):
                dead.append(filename)
                continue
            try:
                displayName, lastPlayed, versionInfo = getWorldInfo(filename)
                action = self.recentWorldsMenu.addAction(displayName)
                action._editWorld = _triggered(filename)
                action.triggered.connect(action._editWorld)
            except EnvironmentError as e:
                log.exception("Failed to load world info")

        if len(dead):
            for f in dead:
                recentWorlds.remove(f)
            RecentFilesSetting.setValue(recentWorlds)

        self.recentWorldsButton.setMenu(self.recentWorldsMenu)

    def reloadList(self):
        try:
            itemData = self.savesFolderComboBox.itemData(
                self.savesFolderComboBox.currentIndex())
            if itemData is None:
                log.error("No item selected in savesFolderComboBox!!(?)")
                return
            saveFileDir, instanceIndex = itemData
            if instanceIndex is not None:
                # disable version selector, update resource packs(?)
                pass
            if not os.path.isdir(saveFileDir):
                raise IOError(
                    u"Could not find the Minecraft saves directory!\n\n({0} was not found or is not a directory)"
                    .format(saveFileDir))

            log.info("Scanning %s for worlds...", saveFileDir)
            potentialWorlds = os.listdir(saveFileDir)
            potentialWorlds = [
                os.path.join(saveFileDir, p) for p in potentialWorlds
            ]
            worldFiles = [
                p for p in potentialWorlds if isLevel(AnvilWorldAdapter, p)
            ]

            self.worldListModel = WorldListModel(worldFiles)
            self.worldListView.setModel(self.worldListModel)

            if len(self.worldListModel.worlds):
                self.worldListView.setFocus()
                self.worldListView.setCurrentIndex(
                    self.worldListModel.createIndex(0, 0))
                self.showWorld(self.worldListModel.worlds[0][0])

        except EnvironmentError as e:
            setWidgetError(self, e)

    def openWorldClicked(self):
        QtGui.qApp.chooseOpenWorld()

    _currentFilename = None

    def worldListItemClicked(self, index):
        filename = index.data()
        if filename != self._currentFilename:
            self._currentFilename = filename
            self.showWorld(filename)

    def worldListItemDoubleClicked(self, index):
        row = index.row()
        self.accept()
        self.editWorldClicked.emit(self.worldListModel.worlds[row][0])

    def showWorld(self, filename):
        self.removeWorldView()

        try:
            worldEditor = worldeditor.WorldEditor(filename, readonly=True)
            resLoader = QtGui.qApp.getResourceLoaderForFilename(filename)
            blockModels = BlockModels(worldEditor.blocktypes, resLoader)
            textureAtlas = TextureAtlas(worldEditor, resLoader, blockModels)

        except (EnvironmentError, LevelFormatError, zipfile.BadZipfile) as e:
            self.errorWidget = QtGui.QWidget()
            setWidgetError(self.errorWidget, e)
            self.stackedWidget.addWidget(self.errorWidget)
            self.stackedWidget.setCurrentWidget(self.errorWidget)

        else:

            dim = worldEditor.getDimension()
            self.setWorldView(MinimapWorldView(dim, textureAtlas))
            self.chunkLoader = ChunkLoader(dim)
            self.chunkLoader.addClient(self.worldView)
            self.chunkLoader.chunkCompleted.connect(self.worldView.update)

            try:
                player = worldEditor.getPlayer()
                log.info("Centering on single-player player.")
            except PlayerNotFound:
                try:
                    center = worldEditor.worldSpawnPosition()
                    log.info("Centering on spawn position.")
                except AttributeError:
                    log.info("Centering on world center")
                    center = dim.bounds.origin + (dim.bounds.size * 0.5)
            else:
                if player.dimName == dim.dimName:
                    center = Vector(*player.Position)
                    self.worldView.centerOnPoint(center)
                else:
                    center = dim.bounds.origin + (dim.bounds.size * 0.5)

            self.worldView.centerOnPoint(center)
            log.info("Switched world view")

    def setWorldView(self, worldView):
        if self.worldView:
            self.removeWorldView()
        self.worldView = worldView
        self.stackedWidget.addWidget(worldView)
        self.stackedWidget.setCurrentWidget(worldView)

    def removeWorldView(self):
        self.stackedWidget.setCurrentWidget(self.blankWidget)
        QtGui.qApp.processEvents(
        )  # force repaint of stackedWidget to hide old error widget
        if self.worldView:
            log.info("Removing view from WorldListWidget")
            self.worldView.destroy()
            self.stackedWidget.removeWidget(self.worldView)
            self.worldView.setParent(None)
            self.worldView = None
        if self.errorWidget:
            self.stackedWidget.removeWidget(self.errorWidget)
            self.errorWidget = None

        self.chunkLoader = None

    def hide(self):
        self.removeWorldView()
        super(WorldListWidget, self).hide()

    def close(self):
        self.removeWorldView()
        super(WorldListWidget, self).close()

    def reject(self):
        self.removeWorldView()
        super(WorldListWidget, self).reject()

    def showEvent(self, event):
        if self.worldListModel and len(self.worldListModel.worlds):
            self.worldListView.setFocus()
            self.worldListView.setCurrentIndex(
                self.worldListModel.createIndex(0, 0))
            self.showWorld(self.worldListModel.worlds[0][0])

        self.reloadRecentWorlds()

    @profiler.function("worldListLoadTimer")
    def loadTimerFired(self):
        if not self.isVisible():
            self.loadTimer.setInterval(1000)
            return

        if self.chunkLoader:
            try:
                self.chunkLoader.next()
                self.loadTimer.setInterval(0)
            except StopIteration:
                self.loadTimer.setInterval(1000)
        else:
            self.loadTimer.setInterval(1000)

    @property
    def selectedWorldIndex(self):
        indexes = self.worldListView.selectedIndexes()
        if len(indexes):
            return indexes[0]

    editWorldClicked = QtCore.Signal(unicode)
    viewWorldClicked = QtCore.Signal(unicode)
    repairWorldClicked = QtCore.Signal(unicode)
    backupWorldClicked = QtCore.Signal(unicode)

    def editClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.editWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def viewClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.viewWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def repairClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.repairWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def backupClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.backupWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def configureClicked(self):
        installsWidget = MinecraftInstallsDialog()
        installsWidget.exec_()
        self._updateVersionsAndResourcePacks()
Exemple #14
0
    def __init__(self, argv):
        super(MCEditApp, self).__init__(argv)
        MCEditApp.app = self

        self.ensureSingle()

        self.commandLineWorlds = []
        self.parseArgs(argv)

        log.warn("UserFilesDirectory: %s", getUserFilesDirectory())

        # --- Translations ---

        self.transDir = resourcePath('mcedit2/i18n')
        self.transLangs = [
            f[:-3] for f in os.listdir(self.transDir) if f.endswith(".qm")
        ]

        lang = LangSetting.value()

        langFile = self.findLangFile(lang)

        if langFile is None:
            systemLocale = QtCore.QLocale.system()
            lang = systemLocale.name()  # "en_US"
            langFile = self.findLangFile(lang)

            if langFile is None:
                lang = "en"
                langFile = os.path.join(self.transDir, "en.qm")

        chosenLang = lang
        self.translator = QtCore.QTranslator()
        self.translator.load(langFile)
        self.installTranslator(self.translator)

        log.info("Loaded translator. Selected language: %s", lang)

        self.translationsMenu = QtGui.QMenu()
        self.translationsMenu.setTitle(self.tr("Language"))

        self.langActions = []

        for lang in self.transLangs:
            locale = QtCore.QLocale(lang)
            language = locale.nativeLanguageName().title() or lang
            if lang == "pr":
                language = "Pirate"
            langAction = self.translationsMenu.addAction(language)
            langAction.setData(lang)
            langAction.setCheckable(True)
            if lang == chosenLang:
                langAction.setChecked(True)
            self.langActions.append(langAction)

        self.translationsMenu.triggered.connect(self.changeLanguage)

        # --- Necessities ---

        self.setOrganizationName("MCEdit")
        self.setOrganizationDomain("mcedit.net")
        self.setApplicationName("MCEdit")
        self.setWindowIcon(
            QtGui.QIcon(resourcePath("mcedit2/assets/mcedit2/mcediticon.png")))
        styleSheet = file(resourcePath("mcedit2/styles/mcedit2.qcss")).read()
        self.setStyleSheet(styleSheet)

        log.info("Loaded stylesheet.")

        # --- Main Window ---

        self.mainWindow = mainWindow = MCEditMainWindow()

        self.undoGroup = QtGui.QUndoGroup()

        self.tabWidget = self.mainWindow.tabWidget
        self.tabWidget.tabCloseRequested.connect(self.tabCloseRequested)
        self.tabWidget.currentChanged.connect(self.tabChanged)

        log.info("Loaded main window.")

        tttIcon = QtGui.QIcon(
            resourcePath("mcedit2/assets/mcedit2/icons/toolbar_text.png"))

        self.toggleToolbarTextAction = QtGui.QAction(tttIcon, "Toolbar Text",
                                                     self)

        self.toggleToolbarTextAction.setCheckable(True)
        self.toggleToolbarTextAction.setChecked(True)

        self.toggleToolbarTextAction.toggled.connect(self.toggleToolbarText)

        # --- OpenGL ---

        setDefaultFormat()

        # --- Sessions ---

        self._currentSession = None
        self.sessions = []
        self.sessionDockWidgets = []
        self.sessionChanged.connect(self.sessionDidChange)

        # --- Panel Widgets ---
        historyIcon = QtGui.QIcon(
            resourcePath("mcedit2/assets/mcedit2/icons/history.png"))

        self.undoView = QtGui.QUndoView(self.undoGroup)
        self.undoDockWidget = MCEDockWidget("History",
                                            mainWindow,
                                            objectName="HistoryWidget")
        self.undoDockWidget.setWidget(self.undoView)
        self.undoDockWidget.setWindowIcon(historyIcon)
        self.undoDockWidget.setUnfocusedOpacity(0.8)

        mainWindow.addDockWidget(Qt.RightDockWidgetArea, self.undoDockWidget)
        undoToggleAction = self.undoDockWidget.toggleViewAction()
        undoToggleAction.setIcon(historyIcon)
        mainWindow.panelsToolBar.addAction(undoToggleAction)
        self.undoDockWidget.close()

        libraryIcon = QtGui.QIcon(
            resourcePath("mcedit2/assets/mcedit2/icons/library.png"))
        self.libraryWidget = LibraryWidget()
        self.libraryDockWidget = MCEDockWidget("Library",
                                               mainWindow,
                                               objectName="LibraryWidget")
        self.libraryDockWidget.setWidget(self.libraryWidget)
        self.libraryDockWidget.setWindowIcon(libraryIcon)
        self.libraryDockWidget.setUnfocusedOpacity(0.8)

        mainWindow.addDockWidget(Qt.RightDockWidgetArea,
                                 self.libraryDockWidget)

        libraryToggleAction = self.libraryDockWidget.toggleViewAction()
        libraryToggleAction.setIcon(libraryIcon)
        mainWindow.panelsToolBar.addAction(libraryToggleAction)
        self.libraryDockWidget.close()
        self.sessionChanged.connect(self.libraryWidget.sessionDidChange)

        self.libraryWidget.doubleClicked.connect(self.libraryItemDoubleClicked)

        self.globalPanels = [self.undoDockWidget, self.libraryDockWidget]

        log.info("Loaded panels.")

        # --- Debug Widgets ---

        self.debugMenu = self.createDebugMenu()

        self.debugObjectInspector = ObjectInspector(mainWindow)
        self.inspectorDockWidget = MCEDockWidget("Object Inspector",
                                                 mainWindow,
                                                 objectName="InspectorWidget")
        self.inspectorDockWidget.setWidget(self.debugObjectInspector)
        self.debugMenu.addAction(self.inspectorDockWidget.toggleViewAction())
        self.inspectorDockWidget.close()

        self.profileView = ProfilerWidget()
        self.profileDockWidget = MCEDockWidget("Profiler",
                                               mainWindow,
                                               objectName="ProfilerWidget")
        self.profileDockWidget.setWidget(self.profileView)
        self.debugMenu.addAction(self.profileDockWidget.toggleViewAction())
        self.profileDockWidget.close()

        self.textureAtlasView = QtGui.QLabel()
        self.textureAtlasView.setScaledContents(True)
        self.textureAtlasDockWidget = MCEDockWidget(
            "Texture Atlas", mainWindow, objectName="TextureAtlasWidget")

        self.textureAtlasArea = QtGui.QScrollArea()
        self.textureAtlasArea.setWidget(self.textureAtlasView)
        self.textureAtlasDockWidget.setWidget(self.textureAtlasArea)
        self.debugMenu.addAction(
            self.textureAtlasDockWidget.toggleViewAction())
        self.textureAtlasDockWidget.close()

        infoTabs = QtGui.QTabWidget()

        self.cursorInfo = WorldCursorInfo()
        infoTabs.addTab(self.cursorInfo, "Cursor")

        self.viewInfo = WorldViewInfo()
        infoTabs.addTab(self.viewInfo, "View")

        self.loaderInfo = ChunkLoaderInfo()
        infoTabs.addTab(self.loaderInfo, "Loader")

        self.infoDockWidget = MCEDockWidget("Debug Info",
                                            mainWindow,
                                            objectName="DebugInfo")
        self.infoDockWidget.setWidget(infoTabs)
        self.infoDockWidget.close()

        log.info("Loaded debug widgets.")

        # --- Menu Actions ---

        # -- MCEdit menu --
        mainWindow.actionNew_World.triggered.connect(self.createNewWorld)
        mainWindow.actionNew_World.setShortcut(QtGui.QKeySequence.New)

        mainWindow.actionOpen_World.triggered.connect(self.chooseOpenWorld)
        mainWindow.actionOpen_World.setShortcut(QtGui.QKeySequence.Open)

        mainWindow.actionShow_World_List.triggered.connect(self.showWorldList)
        mainWindow.actionShow_World_List.setShortcut(
            QtGui.QKeySequence("Ctrl+L"))

        mainWindow.actionSave_World.triggered.connect(self.saveCurrentWorld)
        mainWindow.actionSave_World.setShortcut(QtGui.QKeySequence.Save)

        mainWindow.actionSave_World_As.triggered.connect(
            self.saveCurrentWorldAs)
        mainWindow.actionSave_World_As.setShortcut(QtGui.QKeySequence.SaveAs)

        mainWindow.actionClose_World.triggered.connect(self.closeCurrentTab)
        mainWindow.actionClose_World.setShortcut(QtGui.QKeySequence.Close)

        mainWindow.actionExit_MCEdit.triggered.connect(self.exitEditor)
        mainWindow.actionExit_MCEdit.setShortcut(QtGui.QKeySequence.Quit)

        # -- Help menu --
        mainWindow.actionAbout_MCEdit.triggered.connect(self.showAbout)
        mainWindow.actionAbout_MCEdit.setShortcut(QtGui.QKeySequence.Quit)

        # -- Window Menu --
        mainWindow.menuWindow.addAction(self.undoDockWidget.toggleViewAction())
        mainWindow.menuWindow.addAction(
            self.libraryDockWidget.toggleViewAction())

        # -- Options Menu --
        mainWindow.actionEnable_Lighting_Updates.setChecked(
            EnableLightingSetting.value())
        mainWindow.actionEnable_Lighting_Updates.toggled.connect(
            EnableLightingSetting.setValue)

        EnableLightingSetting.valueChanged.connect(self.enableLightingChanged)
        self.enableLightingChanged(EnableLightingSetting.value())

        mainWindow.actionPreferences.triggered.connect(self.showPrefsDialog)
        mainWindow.actionConfigure_Blocks_Items.triggered.connect(
            self.showConfigureBlocksDialog)
        mainWindow.actionConfigure_Blocks_Items.setEnabled(False)
        mainWindow.actionPlugins.triggered.connect(self.showPluginsDialog)

        mainWindow.actionEnable_Developer_Mode.setChecked(
            DevModeSetting.value())
        mainWindow.actionEnable_Developer_Mode.toggled.connect(
            DevModeSetting.setValue)
        DevModeSetting.valueChanged.connect(self.toggleDeveloperMode)
        self.toggleDeveloperMode(DevModeSetting.value())

        mainWindow.menuOptions.addMenu(self.translationsMenu)

        log.info("Loaded menus.")

        # --- World List ---

        self.worldList = WorldListWidget(mainWindow)
        self.worldList.editWorldClicked.connect(self.editWorldFromList)
        self.worldList.viewWorldClicked.connect(self.viewWorldFromList)
        self.worldList.backupWorldClicked.connect(self.backupWorldFromList)
        self.worldList.repairWorldClicked.connect(self.repairWorldFromList)

        log.info("Loaded world list.")

        # --- Status Bar ---

        self.positionLabel = QtGui.QLabel("xx, yy, zz", minimumWidth=100)
        self.biomeLabel = QtGui.QLabel("Nowhere", minimumWidth=100)
        self.blocktypeLabel = QtGui.QLabel("(-1:-1)minecraft:rocktonium",
                                           minimumWidth=250)
        self.blockNameLabel = QtGui.QLabel("rocktonium", minimumWidth=150)
        self.cpsLabel = QtGui.QLabel("-1 cps", minimumWidth=65)
        self.fpsLabel = QtGui.QLabel("-1 fps", minimumWidth=65)

        statusBar = mainWindow.statusBar()
        statusBar.addPermanentWidget(self.positionLabel)
        statusBar.addPermanentWidget(self.biomeLabel)
        statusBar.addPermanentWidget(self.blocktypeLabel)
        statusBar.addPermanentWidget(self.blockNameLabel)
        statusBar.addPermanentWidget(self.cpsLabel)
        statusBar.addPermanentWidget(self.fpsLabel)

        log.info("Loaded status bar.")

        # --- Load settings ---

        mainWindow.loadSettings()
        self.updateRecentFilesMenu()

        log.info("Loaded settings.")

        # --- App Dialogs ---

        # Qt weirdness - initializing QDialog with parent puts the dialog at 0,
        # 0 instead of centering it on the parent. Have to set the parent explicitly
        # and put the Qt.Dialog flag back on since changing the parent resets the
        # window flags...

        self.prefsDialog = prefsdialog.PrefsDialog(None)
        self.prefsDialog.setParent(mainWindow)
        self.prefsDialog.setWindowFlags(Qt.Dialog)

        self.configureBlocksDialog = configure_blocks.ConfigureBlocksDialog(
            None)
        self.configureBlocksDialog.finished.connect(
            self.configureBlocksFinished)
        self.configureBlocksDialog.setParent(mainWindow)
        self.configureBlocksDialog.setWindowFlags(Qt.Dialog)

        self.pluginsDialog = PluginsDialog()
        self.pluginsDialog.setParent(mainWindow)
        self.pluginsDialog.setWindowFlags(Qt.Dialog)

        log.info("Loaded app dialogs.")

        # --- Loader timer ---

        self.loadTimer = timer = LoaderTimer(self)
        timer.setInterval(0)
        timer.timeout.connect(self.loadTimerFired)
        timer.start()
        log.info("Loading timer started")

        mainWindow.showMaximized()
Exemple #15
0
    def __init__(self, argv):
        super(MCEditApp, self).__init__(argv)
        MCEditApp.app = self

        minecraftinstall.GetInstalls().ensureValidInstall()
        self.ensureSingle()

        self.commandLineWorlds = []
        self.parseArgs(argv)

        log.warn("UserFilesDirectory: %s", getUserFilesDirectory())

        # --- Necessities ---

        translator = QtCore.QTranslator()
        translator.load(resourcePath('mcedit2/i18n/en_US.ts'))
        self.installTranslator(translator)

        log.info("Loaded translator.")

        self.setOrganizationName("MCEdit")
        self.setOrganizationDomain("mcedit.net")
        self.setApplicationName("MCEdit")
        self.setWindowIcon(
            QtGui.QIcon(resourcePath("mcedit2/assets/mcedit2/mcediticon.png")))
        styleSheet = file(resourcePath("mcedit2/styles/mcedit2.qcss")).read()
        self.setStyleSheet(styleSheet)

        log.info("Loaded stylesheet.")

        # --- Main Window ---

        self.mainWindow = mainWindow = MCEditMainWindow()

        self.undoGroup = QtGui.QUndoGroup()

        self.tabWidget = self.mainWindow.tabWidget
        self.tabWidget.tabCloseRequested.connect(self.tabCloseRequested)
        self.tabWidget.currentChanged.connect(self.tabChanged)

        log.info("Loaded main window.")

        # --- OpenGL ---

        setDefaultFormat()

        # --- Sessions ---

        self._currentSession = None
        self.sessions = []
        self.sessionDockWidgets = []
        self.sessionChanged.connect(self.sessionDidChange)

        # --- Panel Widgets ---

        self.undoView = QtGui.QUndoView(self.undoGroup)
        self.undoDockWidget = QtGui.QDockWidget("History",
                                                mainWindow,
                                                objectName="HistoryWidget")
        self.undoDockWidget.setWidget(self.undoView)
        mainWindow.addDockWidget(Qt.RightDockWidgetArea, self.undoDockWidget)
        mainWindow.panelsToolBar.addAction(
            self.undoDockWidget.toggleViewAction())
        self.undoDockWidget.close()

        self.logViewWidget = LogViewFrame(mainWindow)
        self.logViewDockWidget = QtGui.QDockWidget("Error Log",
                                                   mainWindow,
                                                   objectName="ErrorsWidget")
        self.logViewDockWidget.setWidget(self.logViewWidget)
        mainWindow.addDockWidget(Qt.BottomDockWidgetArea,
                                 self.logViewDockWidget)
        mainWindow.panelsToolBar.addAction(
            self.logViewDockWidget.toggleViewAction())
        self.logViewDockWidget.close()

        self.libraryView = LibraryWidget()
        self.libraryDockWidget = QtGui.QDockWidget("Library",
                                                   mainWindow,
                                                   objectName="LibraryWidget")
        self.libraryDockWidget.setWidget(self.libraryView)
        mainWindow.addDockWidget(Qt.RightDockWidgetArea,
                                 self.libraryDockWidget)
        mainWindow.panelsToolBar.addAction(
            self.libraryDockWidget.toggleViewAction())
        self.libraryDockWidget.close()

        self.libraryView.doubleClicked.connect(self.libraryItemDoubleClicked)

        self.globalPanels = [
            self.undoDockWidget, self.logViewDockWidget, self.libraryDockWidget
        ]

        log.info("Loaded panels.")

        # --- Debug Widgets ---

        self.debugMenu = self.createDebugMenu()

        self.debugObjectInspector = ObjectInspector(mainWindow)
        self.inspectorDockWidget = QtGui.QDockWidget(
            "Inspector", mainWindow, objectName="InspectorWidget")
        self.inspectorDockWidget.setWidget(self.debugObjectInspector)
        self.debugMenu.addAction(self.inspectorDockWidget.toggleViewAction())
        self.inspectorDockWidget.close()

        self.profileView = ProfilerWidget()
        self.profileDockWidget = QtGui.QDockWidget("Profiler",
                                                   mainWindow,
                                                   objectName="ProfilerWidget")
        self.profileDockWidget.setWidget(self.profileView)
        self.debugMenu.addAction(self.profileDockWidget.toggleViewAction())
        self.profileDockWidget.close()

        self.textureAtlasView = QtGui.QLabel()
        self.textureAtlasView.setScaledContents(True)
        self.textureAtlasDockWidget = QtGui.QDockWidget(
            "Texture Atlas", mainWindow, objectName="TextureAtlasWidget")

        self.textureAtlasArea = QtGui.QScrollArea()
        self.textureAtlasArea.setWidget(self.textureAtlasView)
        self.textureAtlasDockWidget.setWidget(self.textureAtlasArea)
        self.debugMenu.addAction(
            self.textureAtlasDockWidget.toggleViewAction())
        self.textureAtlasDockWidget.close()

        infoTabs = QtGui.QTabWidget()

        self.cursorInfo = WorldCursorInfo()
        infoTabs.addTab(self.cursorInfo, "Cursor")

        self.viewInfo = WorldViewInfo()
        infoTabs.addTab(self.viewInfo, "View")

        self.loaderInfo = ChunkLoaderInfo()
        infoTabs.addTab(self.loaderInfo, "Loader")

        self.infoDockWidget = QtGui.QDockWidget("Debug Info",
                                                mainWindow,
                                                objectName="DebugInfo")
        self.infoDockWidget.setWidget(infoTabs)
        self.infoDockWidget.close()

        log.info("Loaded debug widgets.")

        # --- Menu Actions ---

        # -- MCEdit menu --
        mainWindow.actionNew_World.triggered.connect(self.createNewWorld)
        mainWindow.actionNew_World.setShortcut(QtGui.QKeySequence.New)

        mainWindow.actionOpen_World.triggered.connect(self.chooseOpenWorld)
        mainWindow.actionOpen_World.setShortcut(QtGui.QKeySequence.Open)

        mainWindow.actionShow_World_List.triggered.connect(self.showWorldList)
        mainWindow.actionShow_World_List.setShortcut(
            QtGui.QKeySequence("Ctrl+L"))

        mainWindow.actionSave_World.triggered.connect(self.saveCurrentWorld)
        mainWindow.actionSave_World.setShortcut(QtGui.QKeySequence.Save)

        mainWindow.actionSave_World_As.triggered.connect(
            self.saveCurrentWorldAs)
        mainWindow.actionSave_World_As.setShortcut(QtGui.QKeySequence.SaveAs)

        mainWindow.actionClose_World.triggered.connect(self.closeCurrentTab)
        mainWindow.actionClose_World.setShortcut(QtGui.QKeySequence.Close)

        mainWindow.actionExit_MCEdit.triggered.connect(self.exitEditor)
        mainWindow.actionExit_MCEdit.setShortcut(QtGui.QKeySequence.Quit)

        # -- Help menu --
        mainWindow.actionAbout_MCEdit.triggered.connect(self.showAbout)
        mainWindow.actionAbout_MCEdit.setShortcut(QtGui.QKeySequence.Quit)

        # -- Window Menu --
        mainWindow.menuWindow.addAction(self.undoDockWidget.toggleViewAction())
        mainWindow.menuWindow.addAction(
            self.logViewDockWidget.toggleViewAction())
        mainWindow.menuWindow.addAction(
            self.libraryDockWidget.toggleViewAction())

        # -- Options Menu --
        mainWindow.actionEnable_Lighting_Updates.setChecked(
            EnableLightingSetting.value())
        mainWindow.actionEnable_Lighting_Updates.toggled.connect(
            EnableLightingSetting.setValue)

        EnableLightingSetting.valueChanged.connect(self.enableLightingChanged)
        self.enableLightingChanged(EnableLightingSetting.value())

        mainWindow.actionPreferences.triggered.connect(self.showPrefsDialog)
        mainWindow.actionConfigure_Blocks_Items.triggered.connect(
            self.showConfigureBlocksDialog)
        mainWindow.actionPlugins.triggered.connect(self.showPluginsDialog)

        mainWindow.actionEnable_Developer_Mode.setChecked(
            DevModeSetting.value())
        mainWindow.actionEnable_Developer_Mode.toggled.connect(
            DevModeSetting.setValue)
        DevModeSetting.valueChanged.connect(self.toggleDeveloperMode)
        self.toggleDeveloperMode(DevModeSetting.value())

        log.info("Loaded menus.")

        # --- World List ---

        self.worldList = WorldListWidget(mainWindow)
        self.worldList.editWorldClicked.connect(self.editWorldFromList)
        self.worldList.viewWorldClicked.connect(self.viewWorldFromList)
        self.worldList.backupWorldClicked.connect(self.backupWorldFromList)
        self.worldList.repairWorldClicked.connect(self.repairWorldFromList)

        log.info("Loaded world list.")

        # --- Status Bar ---

        self.positionLabel = QtGui.QLabel("xx, yy, zz", minimumWidth=100)
        self.biomeLabel = QtGui.QLabel("Nowhere", minimumWidth=100)
        self.blocktypeLabel = QtGui.QLabel("(-1:-1)minecraft:rocktonium",
                                           minimumWidth=250)
        self.blockNameLabel = QtGui.QLabel("rocktonium", minimumWidth=150)
        self.cpsLabel = QtGui.QLabel("-1 cps", minimumWidth=65)
        self.fpsLabel = QtGui.QLabel("-1 fps", minimumWidth=65)

        statusBar = mainWindow.statusBar()
        statusBar.addPermanentWidget(self.positionLabel)
        statusBar.addPermanentWidget(self.biomeLabel)
        statusBar.addPermanentWidget(self.blocktypeLabel)
        statusBar.addPermanentWidget(self.blockNameLabel)
        statusBar.addPermanentWidget(self.cpsLabel)
        statusBar.addPermanentWidget(self.fpsLabel)

        log.info("Loaded status bar.")

        # --- Load settings ---

        mainWindow.loadSettings()
        self.updateRecentFilesMenu()

        log.info("Loaded settings.")

        # --- App Dialogs ---

        self.prefsDialog = prefsdialog.PrefsDialog(None)
        self.configureBlocksDialog = configureblocksdialog.ConfigureBlocksDialog(
            None)
        self.configureBlocksDialog.finished.connect(
            self.configureBlocksFinished)

        # Qt weirdness - initializing QDialog with parent puts the dialog at 0,0 instead of
        # centering it on the parent. Have to set the parent explicitly and put the Qt.Dialog flag back on
        # since changing the parent resets the window flags...
        self.prefsDialog.setParent(mainWindow)
        self.prefsDialog.setWindowFlags(Qt.Dialog)

        self.configureBlocksDialog.setParent(mainWindow)
        self.configureBlocksDialog.setWindowFlags(Qt.Dialog)

        self.pluginsDialog = PluginsDialog()
        self.pluginsDialog.setParent(mainWindow)
        self.pluginsDialog.setWindowFlags(Qt.Dialog)

        log.info("Loaded app dialogs.")

        # --- Loader timer ---

        self.loadTimer = timer = LoaderTimer(self)
        timer.setInterval(0)
        timer.timeout.connect(self.loadTimerFired)
        timer.start()
        log.info("Loading timer started")

        mainWindow.showMaximized()

        QtCore.QTimer.singleShot(0, self.didFinishLaunching)
Exemple #16
0
    def __init__(self, parent=None):
        super(WorldListWidget, self).__init__(parent, f=Qt.Tool)
        self.setWindowTitle("World List")
        self.setWindowModality(Qt.NonModal)
        self.setupUi(self)

        self.worldView = None
        self.chunkLoader = None

        self.errorWidget = None
        self.blankWidget = QtGui.QWidget()
        self.stackedWidget.addWidget(self.blankWidget)

        self.editButton.clicked.connect(self.editClicked)
        self.cancelButton.clicked.connect(self.reject)
        self.showListAgainInput.setEnabled(False)

        self.viewButton.clicked.connect(self.viewClicked)

        self.openWorldButton.clicked.connect(self.openWorldClicked)

        self.repairButton.clicked.connect(self.repairClicked)
        self.repairButton.setEnabled(False)
        self.backupButton.clicked.connect(self.backupClicked)
        self.backupButton.setEnabled(False)
        self.configureButton.clicked.connect(self.configureClicked)

        self.chooseSavesFolderButton.clicked.connect(self.chooseSavesFolder)

        centerWidgetInScreen(self, 0.75)

        delegate = WorldListItemDelegate()
        self.worldListView.setItemDelegate(delegate)
        delegate.setParent(
            self.worldListView
        )  # PYSIDE-152: get the view widget to the drawPrimitive call

        self.worldListView.clicked.connect(self.worldListItemClicked)
        self.worldListView.doubleClicked.connect(
            self.worldListItemDoubleClicked)

        self.loadTimer = LoaderTimer(interval=0, timeout=self.loadTimerFired)
        self.loadTimer.start()

        self._updateInstalls()

        try:
            savesFolders = WorldListSettings.allSavesFolders.value()
            for filename in savesFolders:
                if not os.path.isdir(filename):
                    continue
                dirname, basename = os.path.split(filename)
                displayName = os.sep.join(
                    dirname.split(os.sep)[-2:] + [basename])
                self.savesFolderComboBox.addItem(displayName, filename)
        except (ValueError, KeyError) as e:
            log.warn("Failed to load saves folder list.")

        currentFolder = WorldListSettings.currentSavesFolder.value()
        if os.path.isdir(currentFolder):
            index = self.savesFolderComboBox.findData(currentFolder)
            if index != -1:
                self.savesFolderComboBox.setCurrentIndex(index)

        self.savesFolderComboBox.currentIndexChanged.connect(
            self.savesFolderChanged)
        self.minecraftInstallBox.currentIndexChanged.connect(
            self.currentInstallChanged)
        self.minecraftVersionBox.currentIndexChanged[str].connect(
            minecraftinstall.currentVersionOption.setValue)
        self.resourcePackBox.currentIndexChanged.connect(
            self.resourcePackChanged)
        self.worldListModel = None
        self.reloadList()
        self.reloadRecentWorlds()
Exemple #17
0
class WorldListWidget(QtGui.QDialog, Ui_worldList):
    def __init__(self, parent=None):
        super(WorldListWidget, self).__init__(parent, f=Qt.Tool)
        self.setWindowTitle("World List")
        self.setWindowModality(Qt.NonModal)
        self.setupUi(self)

        self.worldView = None
        self.chunkLoader = None

        self.errorWidget = None
        self.blankWidget = QtGui.QWidget()
        self.stackedWidget.addWidget(self.blankWidget)

        self.editButton.clicked.connect(self.editClicked)
        self.cancelButton.clicked.connect(self.reject)
        self.showListAgainInput.setEnabled(False)

        self.viewButton.clicked.connect(self.viewClicked)

        self.openWorldButton.clicked.connect(self.openWorldClicked)

        self.repairButton.clicked.connect(self.repairClicked)
        self.repairButton.setEnabled(False)
        self.backupButton.clicked.connect(self.backupClicked)
        self.backupButton.setEnabled(False)
        self.configureButton.clicked.connect(self.configureClicked)

        self.chooseSavesFolderButton.clicked.connect(self.chooseSavesFolder)

        centerWidgetInScreen(self, 0.75)

        delegate = WorldListItemDelegate()
        self.worldListView.setItemDelegate(delegate)
        delegate.setParent(
            self.worldListView
        )  # PYSIDE-152: get the view widget to the drawPrimitive call

        self.worldListView.clicked.connect(self.worldListItemClicked)
        self.worldListView.doubleClicked.connect(
            self.worldListItemDoubleClicked)

        self.loadTimer = LoaderTimer(interval=0, timeout=self.loadTimerFired)
        self.loadTimer.start()

        self._updateInstalls()

        try:
            savesFolders = WorldListSettings.allSavesFolders.value()
            for filename in savesFolders:
                if not os.path.isdir(filename):
                    continue
                dirname, basename = os.path.split(filename)
                displayName = os.sep.join(
                    dirname.split(os.sep)[-2:] + [basename])
                self.savesFolderComboBox.addItem(displayName, filename)
        except (ValueError, KeyError) as e:
            log.warn("Failed to load saves folder list.")

        currentFolder = WorldListSettings.currentSavesFolder.value()
        if os.path.isdir(currentFolder):
            index = self.savesFolderComboBox.findData(currentFolder)
            if index != -1:
                self.savesFolderComboBox.setCurrentIndex(index)

        self.savesFolderComboBox.currentIndexChanged.connect(
            self.savesFolderChanged)
        self.minecraftInstallBox.currentIndexChanged.connect(
            self.currentInstallChanged)
        self.minecraftVersionBox.currentIndexChanged[str].connect(
            minecraftinstall.currentVersionOption.setValue)
        self.resourcePackBox.currentIndexChanged.connect(
            self.resourcePackChanged)
        self.worldListModel = None
        self.reloadList()
        self.reloadRecentWorlds()

    def currentInstallChanged(self, index):
        path = self.minecraftInstallBox.itemData(index)
        minecraftinstall.currentInstallOption.setValue(path)

    def resourcePackChanged(self, index):
        if index == 0:
            minecraftinstall.currentResourcePackOption.setValue("")
        else:
            minecraftinstall.currentResourcePackOption.setValue(
                self.resourcePackBox.currentText())

    def _updateInstalls(self):
        self.minecraftInstallBox.clear()

        for install in minecraftinstall.GetInstalls().installs:
            self.minecraftInstallBox.addItem(install.name, install.path)
            for saveDir in install.getSaveDirs():
                self.savesFolderComboBox.addItem(
                    install.name + os.sep + os.path.basename(saveDir), saveDir)

        for instance in minecraftinstall.GetInstalls().instances:
            saveDir = instance.saveFileDir
            self.savesFolderComboBox.addItem(
                instance.name + os.sep + os.path.basename(saveDir), saveDir)

        path = minecraftinstall.GetInstalls().selectedInstallPath()
        index = self.minecraftInstallBox.findData(path)
        self.minecraftInstallBox.setCurrentIndex(index)

        self._updateVersionsAndResourcePacks()

    def _updateVersionsAndResourcePacks(self):
        self.minecraftVersionBox.clear()
        self.resourcePackBox.clear()
        self.resourcePackBox.addItem(self.tr("(No resource pack)"))

        path = minecraftinstall.currentInstallOption.value()
        install = minecraftinstall.GetInstalls().getInstall(path)

        if install:
            for version in sorted(install.versions, reverse=True):
                self.minecraftVersionBox.addItem(version)

            for resourcePack in sorted(install.resourcePacks):
                self.resourcePackBox.addItem(resourcePack)

    def chooseSavesFolder(self):
        startingDir = WorldListSettings.lastChosenSavesFolder.value()
        if startingDir == '' or not os.path.isdir(startingDir):
            startingDir = os.path.expanduser(b"~")

        filename = QtGui.QFileDialog.getExistingDirectory(
            self, self.tr("Choose Saves Folder"), startingDir)

        if filename:
            log.info("Adding saves folder %s", filename)

            savesFolders = WorldListSettings.allSavesFolders.value()
            savesFolders.append(filename)
            WorldListSettings.allSavesFolders.setValue(savesFolders)

            dirname, basename = os.path.split(filename)
            displayName = os.sep.join(dirname.split(os.sep)[-2:] + [basename])
            WorldListSettings.lastChosenSavesFolder.setValue(filename)
            self.savesFolderComboBox.addItem(displayName, filename)
            self.savesFolderComboBox.setCurrentIndex(
                self.savesFolderComboBox.count() - 1)

    def reloadRecentWorlds(self):
        recentWorlds = RecentFilesSetting.value()
        self.recentWorldsMenu = QtGui.QMenu()

        def _triggered(f):
            def triggered():
                self.accept()
                self.editWorldClicked.emit(f)

            return triggered

        dead = []
        for filename in recentWorlds:
            if not os.path.exists(filename):
                dead.append(filename)
                continue
            try:
                displayName, lastPlayed, versionInfo = WorldEditor.getWorldInfo(
                    filename)
                action = self.recentWorldsMenu.addAction(displayName)
                action._editWorld = _triggered(filename)
                action.triggered.connect(action._editWorld)
            except EnvironmentError as e:
                log.exception("Failed to load world info")

        if len(dead):
            for f in dead:
                recentWorlds.remove(f)
            RecentFilesSetting.setValue(recentWorlds)

        self.recentWorldsButton.setMenu(self.recentWorldsMenu)

    def savesFolderChanged(self):
        currentFolder = self.savesFolderComboBox.itemData(
            self.savesFolderComboBox.currentIndex())
        WorldListSettings.currentSavesFolder.setValue(currentFolder)

        self.reloadList()
        if len(self.worldListModel.worlds):
            self.worldListView.setFocus()
            self.worldListView.setCurrentIndex(
                self.worldListModel.createIndex(0, 0))
            self.showWorld(self.worldListModel.worlds[0][0])
        else:
            self.removeWorldView()

    def reloadList(self):
        try:
            saveFileDir = self.savesFolderComboBox.itemData(
                self.savesFolderComboBox.currentIndex())
            if saveFileDir is None:
                log.error("No item selected in savesFolderComboBox!!(?)")
                return
            if not os.path.isdir(saveFileDir):
                raise IOError(
                    u"Could not find the Minecraft saves directory!\n\n({0} was not found or is not a directory)"
                    .format(saveFileDir))

            log.info("Scanning %s for worlds...", saveFileDir)
            potentialWorlds = os.listdir(saveFileDir)
            potentialWorlds = [
                os.path.join(saveFileDir, p) for p in potentialWorlds
            ]
            worldFiles = [
                p for p in potentialWorlds if isLevel(AnvilWorldAdapter, p)
            ]

            self.worldListModel = WorldListModel(worldFiles)
            self.worldListView.setModel(self.worldListModel)

        except Exception as e:
            setWidgetError(
                self, e, "An error occurred while scanning the saves folder.")

    def openWorldClicked(self):
        QtGui.qApp.chooseOpenWorld()

    _currentFilename = None

    def worldListItemClicked(self, index):
        filename = index.data()
        self.showWorld(filename)

    def worldListItemDoubleClicked(self, index):
        row = index.row()
        self.accept()
        self.editWorldClicked.emit(self.worldListModel.worlds[row][0])

    def showWorld(self, filename):
        if filename == self._currentFilename:
            return
        self._currentFilename = filename

        self.removeWorldView()

        try:
            worldEditor = worldeditor.WorldEditor(filename, readonly=True)

        except (EnvironmentError, LevelFormatError, zipfile.BadZipfile) as e:
            self.errorWidget = QtGui.QWidget()
            setWidgetError(
                self.errorWidget, e,
                "An error occurred while reading the world %s." % filename)
            self.stackedWidget.addWidget(self.errorWidget)
            self.stackedWidget.setCurrentWidget(self.errorWidget)

        else:

            dim = worldEditor.getDimension()
            self.setWorldView(MinimapWorldView(dim))
            self.chunkLoader = ChunkLoader(dim)
            self.chunkLoader.addClient(self.worldView)
            self.chunkLoader.chunkCompleted.connect(self.worldView.update)

            try:
                try:
                    player = worldEditor.getPlayer()
                    log.info("Centering on single-player player.")
                except (PlayerNotFound, NBTFormatError):
                    try:
                        center = worldEditor.getWorldMetadata().Spawn
                        log.info("Centering on spawn position.")
                    except AttributeError:
                        log.info("Centering on world center")
                        center = dim.bounds.origin + (dim.bounds.size * 0.5)
                else:
                    if player.dimName == dim.dimName:
                        center = Vector(*player.Position)
                        self.worldView.centerOnPoint(center)
                    else:
                        center = dim.bounds.origin + (dim.bounds.size * 0.5)

                self.worldView.centerOnPoint(center)
            except Exception as e:
                log.exception("Error while centering view in world list: %s",
                              e)

            log.info("Switched world view")

    def setWorldView(self, worldView):
        if self.worldView:
            self.removeWorldView()
        self.worldView = worldView
        self.stackedWidget.addWidget(worldView)
        self.stackedWidget.setCurrentWidget(worldView)

    def removeWorldView(self):
        self.stackedWidget.setCurrentWidget(self.blankWidget)
        QtGui.qApp.processEvents(
        )  # force repaint of stackedWidget to hide old error widget
        if self.worldView:
            log.info("Removing view from WorldListWidget")
            self.worldView.dealloc()
            self.stackedWidget.removeWidget(self.worldView)
            self.worldView.setParent(None)
            self.worldView = None
        if self.errorWidget:
            self.stackedWidget.removeWidget(self.errorWidget)
            self.errorWidget = None

        self.chunkLoader = None

        # ensure WorldView gets freed now and not later
        # if it is freed later, it will call makeCurrent and ruin another view's render
        import gc
        gc.collect()

    def hide(self):
        self.removeWorldView()
        super(WorldListWidget, self).hide()

    def close(self):
        self.removeWorldView()
        super(WorldListWidget, self).close()

    def reject(self):
        self.removeWorldView()
        super(WorldListWidget, self).reject()

    def showEvent(self, event):
        if self.worldListModel and len(self.worldListModel.worlds):
            self.worldListView.setFocus()
            self.worldListView.setCurrentIndex(
                self.worldListModel.createIndex(0, 0))
            self.showWorld(self.worldListModel.worlds[0][0])

        self.reloadRecentWorlds()

    @profiler.function("worldListLoadTimer")
    def loadTimerFired(self):
        if not self.isVisible():
            self.loadTimer.setInterval(1000)
            return

        if self.chunkLoader:
            try:
                self.chunkLoader.next()
                self.loadTimer.setInterval(0)
            except StopIteration:
                self.loadTimer.setInterval(1000)
        else:
            self.loadTimer.setInterval(1000)

    @property
    def selectedWorldIndex(self):
        indexes = self.worldListView.selectedIndexes()
        if len(indexes):
            return indexes[0]

    editWorldClicked = QtCore.Signal(unicode)
    viewWorldClicked = QtCore.Signal(unicode)
    repairWorldClicked = QtCore.Signal(unicode)
    backupWorldClicked = QtCore.Signal(unicode)

    def editClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.editWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def viewClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.viewWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def repairClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.repairWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def backupClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.backupWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def configureClicked(self):
        installsWidget = MinecraftInstallsDialog()
        installsWidget.exec_()
        self._updateInstalls()
Exemple #18
0
class WorldListWidget(QtGui.QDialog):
    def __init__(self, parent=None, f=0):
        super(WorldListWidget, self).__init__(parent, f)
        self.setWindowTitle("World List")
        load_ui('world_list.ui', baseinstance=self)

        self.worldView = None
        self.chunkLoader = None

        self.errorWidget = None
        self.blankWidget = QtGui.QWidget()
        self.stackedWidget.addWidget(self.blankWidget)

        self.editButton.clicked.connect(self.editClicked)
        self.cancelButton.clicked.connect(self.reject)
        self.showListAgainInput.setEnabled(False)

        self.viewButton.clicked.connect(self.viewClicked)
        self.viewButton.setEnabled(False)

        self.openWorldButton.clicked.connect(self.openWorldClicked)

        self.repairButton.clicked.connect(self.repairClicked)
        self.repairButton.setEnabled(False)
        self.backupButton.clicked.connect(self.backupClicked)
        self.backupButton.setEnabled(False)
        self.configureButton.clicked.connect(self.configureClicked)

        centerWidgetInScreen(self, 0.75)

        delegate = WorldListItemDelegate()
        self.worldListView.setItemDelegate(delegate)
        delegate.setParent(self.worldListView)  # PYSIDE-152: get the view widget to the drawPrimitive call

        self.worldListView.clicked.connect(self.worldListItemClicked)
        self.worldListView.doubleClicked.connect(self.worldListItemDoubleClicked)

        self.loadTimer = LoaderTimer(interval=0, timeout=self.loadTimerFired)
        self.loadTimer.start()

        self._updateInstalls()

        self.savesFolderComboBox.currentIndexChanged.connect(self.reloadList)

        self.worldListModel = None
        self.reloadList()
        self.reloadRecentWorlds()

    def _updateInstalls(self):
        for install in minecraftinstall.GetInstalls().installs:
            self.minecraftInstallBox.addItem(install.name)

        self.minecraftInstallBox.setCurrentIndex(minecraftinstall.GetInstalls().selectedInstallIndex())

        self._updateVersionsAndResourcePacks()

    def _updateVersionsAndResourcePacks(self):
        install = minecraftinstall.GetInstalls().getInstall(self.minecraftInstallBox.currentIndex())

        self.minecraftVersionBox.clear()
        for version in sorted(install.versions, reverse=True):
            self.minecraftVersionBox.addItem(version)

        self.resourcePackBox.clear()
        self.resourcePackBox.addItem(self.tr("(No resource pack)"))
        for resourcePack in sorted(install.resourcePacks):
            self.resourcePackBox.addItem(resourcePack)

        self.saveDirs = install.getSaveDirs()
        self.savesFolderComboBox.clear()
        for filename in self.saveDirs:
            self.savesFolderComboBox.addItem(os.path.basename(os.path.dirname(filename)), (filename, None))
        for index, instance in enumerate(minecraftinstall.GetInstalls().instances):  # xxx instanceID?
            self.savesFolderComboBox.addItem(instance.name, (instance.saveFileDir, index))

    def getSelectedIVP(self):
        i = self.minecraftInstallBox.currentIndex()
        install = minecraftinstall.GetInstalls().getInstall(i)
        v = self.minecraftVersionBox.currentText()
        if self.resourcePackBox.currentIndex() > 0:
            p = self.resourcePackBox.currentText()
        else:
            p = None
        return install, v, p

    def reloadRecentWorlds(self):
        recentWorlds = RecentFilesSetting.value()
        self.recentWorldsMenu = QtGui.QMenu()

        def _triggered(f):
            def triggered():
                self.accept()
                self.editWorldClicked.emit(f)
            return triggered

        for filename in recentWorlds:
            try:
                displayName, lastPlayed = getWorldInfo(filename)
                action = self.recentWorldsMenu.addAction(displayName)
                action._editWorld = _triggered(filename)
                action.triggered.connect(action._editWorld)
            except EnvironmentError as e:
                log.exception("Failed to load world info")

        self.recentWorldsButton.setMenu(self.recentWorldsMenu)

    def reloadList(self):
        try:
            itemData = self.savesFolderComboBox.itemData(self.savesFolderComboBox.currentIndex())
            if itemData is None:
                log.error("No item selected in savesFolderComboBox!!(?)")
                return
            saveFileDir, instanceIndex = itemData
            if instanceIndex is not None:
                # disable version selector, update resource packs(?)
                pass
            if not os.path.isdir(saveFileDir):
                raise IOError(u"Could not find the Minecraft saves directory!\n\n({0} was not found or is not a directory)".format(saveFileDir))

            log.info("Scanning %s for worlds...", saveFileDir)
            potentialWorlds = os.listdir(saveFileDir)
            potentialWorlds = [os.path.join(saveFileDir, p) for p in potentialWorlds]
            worldFiles = [p for p in potentialWorlds if isLevel(AnvilWorldAdapter, p)]

            self.worldListModel = WorldListModel(worldFiles)
            self.worldListView.setModel(self.worldListModel)



            if len(self.worldListModel.worlds):
                self.worldListView.setFocus()
                self.worldListView.setCurrentIndex(self.worldListModel.createIndex(0, 0))
                self.showWorld(self.worldListModel.worlds[0][0])

        except EnvironmentError as e:
            setWidgetError(self, e)

    def openWorldClicked(self):
        QtGui.qApp.chooseOpenWorld()

    _currentFilename = None

    def worldListItemClicked(self, index):
        filename = index.data()
        if filename != self._currentFilename:
            self._currentFilename = filename
            self.showWorld(filename)

    def worldListItemDoubleClicked(self, index):
        row = index.row()
        self.accept()
        self.editWorldClicked.emit(self.worldListModel.worlds[row][0])

    def showWorld(self, filename):
        self.removeWorldView()

        try:
            worldEditor = worldeditor.WorldEditor(filename, readonly=True)
            i, v, p = self.getSelectedIVP()
            resLoader = i.getResourceLoader(v, p)
            blockModels = BlockModels(worldEditor.blocktypes, resLoader)
            textureAtlas = TextureAtlas(worldEditor, resLoader, blockModels)

        except (EnvironmentError, LevelFormatError, zipfile.BadZipfile) as e:
            self.errorWidget = QtGui.QWidget()
            setWidgetError(self.errorWidget, e)
            self.stackedWidget.addWidget(self.errorWidget)
            self.stackedWidget.setCurrentWidget(self.errorWidget)

        else:

            dim = worldEditor.getDimension()
            self.setWorldView(MinimapWorldView(dim, textureAtlas))
            self.chunkLoader = ChunkLoader(dim)
            self.chunkLoader.addClient(self.worldView)
            self.chunkLoader.chunkCompleted.connect(self.worldView.update)

            try:
                player = worldEditor.getPlayer()
                log.info("Centering on single-player player.")
            except PlayerNotFound:
                try:
                    center = worldEditor.worldSpawnPosition()
                    log.info("Centering on spawn position.")
                except AttributeError:
                    log.info("Centering on world center")
                    center = dim.bounds.origin + (dim.bounds.size * 0.5)
            else:
                if player.dimName == dim.dimName:
                    center = Vector(*player.Position)
                    self.worldView.centerOnPoint(center)
                else:
                    center = dim.bounds.origin + (dim.bounds.size * 0.5)

            self.worldView.centerOnPoint(center)
            log.info("Switched world view")

    def setWorldView(self, worldView):
        if self.worldView:
            self.removeWorldView()
        self.worldView = worldView
        self.stackedWidget.addWidget(worldView)
        self.stackedWidget.setCurrentWidget(worldView)

    def removeWorldView(self):
        self.stackedWidget.setCurrentWidget(self.blankWidget)
        QtGui.qApp.processEvents()  # force repaint of stackedWidget to hide old error widget
        if self.worldView:
            log.info("Removing view from WorldListWidget")
            self.worldView.textureAtlas.dispose()
            self.worldView.destroy()
            self.stackedWidget.removeWidget(self.worldView)
            self.worldView.setParent(None)
            self.worldView = None
        if self.errorWidget:
            self.stackedWidget.removeWidget(self.errorWidget)
            self.errorWidget = None

        self.chunkLoader = None

    def hide(self):
        self.removeWorldView()
        super(WorldListWidget, self).hide()

    def close(self):
        self.removeWorldView()
        super(WorldListWidget, self).close()

    def reject(self):
        self.removeWorldView()
        super(WorldListWidget, self).reject()

    def showEvent(self, event):
        if self.worldListModel and len(self.worldListModel.worlds):
            self.worldListView.setFocus()
            self.worldListView.setCurrentIndex(self.worldListModel.createIndex(0, 0))
            self.showWorld(self.worldListModel.worlds[0][0])

        self.reloadRecentWorlds()

    @profiler.function("worldListLoadTimer")
    def loadTimerFired(self):
        if not self.isVisible():
            self.loadTimer.setInterval(1000)
            return

        if self.chunkLoader:
            try:
                self.chunkLoader.next()
                self.loadTimer.setInterval(0)
            except StopIteration:
                self.loadTimer.setInterval(1000)
        else:
            self.loadTimer.setInterval(1000)

    @property
    def selectedWorldIndex(self):
        indexes = self.worldListView.selectedIndexes()
        if len(indexes):
            return indexes[0]

    editWorldClicked = QtCore.Signal(unicode)
    viewWorldClicked = QtCore.Signal(unicode)
    repairWorldClicked = QtCore.Signal(unicode)
    backupWorldClicked = QtCore.Signal(unicode)

    def editClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.editWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def viewClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.viewWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def repairClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.repairWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def backupClicked(self):
        index = self.selectedWorldIndex
        if index is not None:
            self.backupWorldClicked.emit(index.data(Qt.DisplayRole))
            self.accept()

    def configureClicked(self):
        installsWidget = MinecraftInstallsDialog()
        installsWidget.exec_()
        self._updateVersionsAndResourcePacks()
Exemple #19
0
def showProgress(text, *tasks, **kwargs):
    """
    Show a progress dialog for the given task(s). Each task should be an iterable,
    yielding progress info as (current, max) or (current, max, statusString) tuples.
    Return the last value yielded by the task.

    :param text:
    :type text:
    :param iter:
    :type iter:
    :param cancel:
    :type cancel:
    :return:
    :rtype:
    """
    progress = None
    cancel = kwargs.pop('cancel', None)
    start = time.time()
    shown = False
    with LoaderTimer.stopCtx():

        dialog = MCEProgressDialog(QtGui.qApp.mainWindow)
        if not cancel:
            dialog.setCancelButtonText(None)
        dialog.setWindowTitle(text)
        dialog.setWindowModality(Qt.WindowModal)
        log.info("Starting progress: %d tasks." % len(tasks))
        totalMaximum = len(tasks) * 100
        for i, task in enumerate(tasks):
            log.info("Task #%d", i)
            task = rescaleProgress(task, i*100, i*100+100)
            for progress in task:
                if isinstance(progress, basestring):
                    current = 0
                    maximum = 0
                    status = progress
                elif isinstance(progress, tuple):
                    if len(progress) > 2:
                        current, maximum, status = progress[:3]
                    else:
                        current, maximum = progress
                        status = ""
                else:
                    current = 0
                    maximum = 0
                    status = ""

                dialog.setValue(current)
                if maximum == 0:
                    # Task progress is indeterminate
                    dialog.setMaximum(0)
                else:
                    dialog.setMaximum(totalMaximum)
                dialog.setLabelText(status)
                if time.time() > start + timeBeforeDialog:
                    if not shown:
                        dialog.show()
                        shown = True
                    QtGui.QApplication.processEvents()

                if dialog.wasCanceled():
                    return False

        dialog.reset()
        return progress
Exemple #20
0
class WorldListWidget(QtGui.QDialog):
    def __init__(self, parent=None, f=0):
        super(WorldListWidget, self).__init__(parent, f)
        self.setWindowTitle("World List")

        self.saveFileDir = None
        self.worldView = None
        self.chunkLoader = None

        self.errorWidget = QtGui.QWidget()

        load_ui('world_list.ui', baseinstance=self)

        self.setLayout(Row(self))

        self.editButton.clicked.connect(self.editClicked)
        self.cancelButton.clicked.connect(self.reject)
        self.showListAgainInput.setEnabled(False)

        self.viewButton.clicked.connect(self.viewClicked)
        self.viewButton.setEnabled(False)

        self.repairButton.clicked.connect(self.repairClicked)
        self.repairButton.setEnabled(False)
        self.backupButton.clicked.connect(self.backupClicked)
        self.backupButton.setEnabled(False)
        self.configureButton.clicked.connect(self.configureClicked)

        screen = QtGui.QApplication.desktop().availableGeometry()
        w = screen.width()
        h = screen.height()
        margin = 0.125
        r = QtCore.QRect(screen.x() + margin * w,
                         screen.y() + margin * h, w - w * 2 * margin,
                         h - h * 2 * margin)

        self.setGeometry(r)

        self.loadTimer = LoaderTimer(interval=0, timeout=self.loadTimerFired)
        self.loadTimer.start()

        for install in minecraftinstall.listInstalls():
            self.minecraftInstallBox.addItem(install.name)
        self.minecraftInstallBox.setCurrentIndex(
            minecraftinstall.selectedInstallIndex())
        self._updateVersionsAndResourcePacks()
        self.reloadList()

    def _updateVersionsAndResourcePacks(self):
        install = minecraftinstall.getInstall(
            self.minecraftInstallBox.currentIndex())
        for version in sorted(install.versions, reverse=True):
            self.minecraftVersionBox.addItem(version)
        self.resourcePackBox.addItem(self.tr("(No resource pack)"))
        for resourcePack in sorted(install.resourcePacks):
            self.resourcePackBox.addItem(resourcePack)
        self.saveFileDir = install.getSaveFileDir()

    def getSelectedIVP(self):
        i = self.minecraftInstallBox.currentIndex()
        install = minecraftinstall.getInstall(i)
        v = self.minecraftVersionBox.currentText()
        if self.resourcePackBox.currentIndex() > 0:
            p = self.resourcePackBox.currentText()
        else:
            p = None
        return install, v, p

    def reloadList(self):
        self.selectedWorldIndex = -1

        self.itemWidgets = []

        try:
            if not os.path.isdir(self.saveFileDir):
                raise IOError(
                    u"Could not find the Minecraft saves directory!\n\n({0} was not found or is not a directory)"
                    .format(self.saveFileDir))

            log.info("Scanning %s for worlds...", self.saveFileDir)
            potentialWorlds = os.listdir(self.saveFileDir)
            potentialWorlds = [
                os.path.join(self.saveFileDir, p) for p in potentialWorlds
            ]
            worldFiles = [
                p for p in potentialWorlds if isLevel(AnvilWorldAdapter, p)
            ]
            worldAdapters = []
            for f in worldFiles:
                try:
                    adapter = findAdapter(f, readonly=True)
                except Exception as e:
                    log.exception("Could not find adapter for %s: %r", f, e)
                    continue
                else:
                    worldAdapters.append(adapter)

            if len(worldAdapters) == 0:
                raise IOError(
                    "No worlds found! You should probably play Minecraft to create your first world."
                )

            column = QtGui.QVBoxLayout()
            column.setContentsMargins(0, 0, 0, 0)
            column.setSpacing(0)

            worldGroup = QtGui.QButtonGroup(self)
            #worldGroup.setExclusive(True)

            for adapter in worldAdapters:
                item = WorldListItemWidget(adapter)
                self.itemWidgets.append(item)

            self.itemWidgets.sort(key=lambda i: i.lastPlayed, reverse=True)

            for i, item in enumerate(self.itemWidgets):
                worldGroup.addButton(item, i)
                column.addWidget(item)
                item.doubleClicked.connect(self.worldListItemDoubleClicked)

            worldGroup.buttonClicked[int].connect(self.worldListItemClicked)

            self.scrollAreaWidgetContents.setLayout(column)

        except EnvironmentError as e:
            setWidgetError(self, e)

    def worldListItemClicked(self, i):
        if self.selectedWorldIndex == i:
            return
        self.selectedWorldIndex = i
        import gc
        gc.collect()
        models = {}
        try:
            worldEditor = worldeditor.WorldEditor(self.itemWidgets[i].filename,
                                                  readonly=True)
        except (EnvironmentError, LevelFormatError) as e:
            setWidgetError(self.errorWidget, e)
            while self.stackedWidget.count():
                self.stackedWidget.removeWidget(self.stackedWidget.widget(0))

            self.worldViewBox.addWidget(self.errorWidget)
        else:
            i, v, p = self.getSelectedIVP()
            blockModels = models.get(worldEditor.blocktypes)
            resLoader = i.getResourceLoader(v, p)
            if blockModels is None:
                models[worldEditor.blocktypes] = blockModels = BlockModels(
                    worldEditor.blocktypes, resLoader)
            textureAtlas = TextureAtlas(worldEditor, resLoader, blockModels)

            dim = worldEditor.getDimension()
            self.setWorldView(MinimapWorldView(dim, textureAtlas))
            self.chunkLoader = ChunkLoader(dim)
            self.chunkLoader.addClient(self.worldView)
            self.chunkLoader.chunkCompleted.connect(self.worldView.update)

            try:
                player = worldEditor.getPlayer()
                log.info("Centering on single-player player.")
            except PlayerNotFound:
                try:
                    center = worldEditor.worldSpawnPosition()
                    log.info("Centering on spawn position.")
                except AttributeError:
                    log.info("Centering on world center")
                    center = dim.bounds.origin + (dim.bounds.size * 0.5)
            else:
                if player.dimName == dim.dimName:
                    center = Vector(*player.Position)
                    self.worldView.centerOnPoint(center)
                else:
                    center = dim.bounds.origin + (dim.bounds.size * 0.5)

            self.worldView.centerOnPoint(center)
            log.info("Switched world view")

    def setWorldView(self, worldView):
        if self.worldView:
            self.removeWorldView()
        self.worldView = worldView
        self.stackedWidget.addWidget(worldView)

    def removeWorldView(self):
        if self.worldView:
            self.worldView.textureAtlas.dispose()
            self.worldView.destroy()
            self.worldView.setParent(None)
            self.stackedWidget.removeWidget(self.worldView)
            self.worldView = None

        self.chunkLoader = None

    def closeEvent(self, event):
        self.removeWorldView()
        self.selectedWorldIndex = -1
        #import gc; gc.collect()

    def showEvent(self, event):
        if len(self.itemWidgets):
            self.itemWidgets[0].click()

    def worldListItemDoubleClicked(self):
        self.editClicked()

    @profiler.function("worldListLoadTimer")
    def loadTimerFired(self):
        if not self.isVisible():
            self.loadTimer.setInterval(1000)
            return

        if self.chunkLoader:
            try:
                self.chunkLoader.next()
                self.loadTimer.setInterval(0)
            except StopIteration:
                self.loadTimer.setInterval(1000)
        else:
            self.loadTimer.setInterval(1000)

    editWorldClicked = QtCore.Signal(unicode)
    viewWorldClicked = QtCore.Signal(unicode)
    repairWorldClicked = QtCore.Signal(unicode)
    backupWorldClicked = QtCore.Signal(unicode)

    def editClicked(self):
        self.editWorldClicked.emit(
            self.itemWidgets[self.selectedWorldIndex].filename)
        self.accept()

    def viewClicked(self):
        self.viewWorldClicked.emit(
            self.itemWidgets[self.selectedWorldIndex].filename)
        self.accept()

    def repairClicked(self):
        self.repairWorldClicked.emit(
            self.itemWidgets[self.selectedWorldIndex].filename)
        self.accept()

    def backupClicked(self):
        self.backupWorldClicked.emit(
            self.itemWidgets[self.selectedWorldIndex].filename)
        self.accept()

    def configureClicked(self):
        installsWidget = MinecraftInstallsDialog()
        installsWidget.exec_()
        self._updateVersionsAndResourcePacks()