From 8b1039fa30a405e2d07ac70eb0284ee4654c619a Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Fri, 15 Jan 2016 21:12:23 +0200 Subject: Organise files into a module structure. --- mesongui.py | 561 ------------------------------------------------------------ 1 file changed, 561 deletions(-) delete mode 100755 mesongui.py (limited to 'mesongui.py') diff --git a/mesongui.py b/mesongui.py deleted file mode 100755 index bdd44bb..0000000 --- a/mesongui.py +++ /dev/null @@ -1,561 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2013-2015 The Meson development team - -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at - -# http://www.apache.org/licenses/LICENSE-2.0 - -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import sys, os, pickle, time, shutil -import build, coredata, environment, mesonlib -from PyQt5 import uic -from PyQt5.QtWidgets import QApplication, QMainWindow, QHeaderView -from PyQt5.QtWidgets import QComboBox, QCheckBox -from PyQt5.QtCore import QAbstractItemModel, QModelIndex, QVariant, QTimer -import PyQt5.QtCore -import PyQt5.QtWidgets - -priv_dir = os.path.split(os.path.abspath(os.path.realpath(__file__)))[0] - -class PathModel(QAbstractItemModel): - def __init__(self, coredata): - super().__init__() - self.coredata = coredata - self.names = ['Prefix', 'Library dir', 'Binary dir', 'Include dir', 'Data dir',\ - 'Man dir', 'Locale dir'] - self.attr_name = ['prefix', 'libdir', 'bindir', 'includedir', 'datadir', \ - 'mandir', 'localedir'] - - def args(self, index): - if index.column() == 1: - editable = PyQt5.QtCore.Qt.ItemIsEditable - else: - editable= 0 - return PyQt5.QtCore.Qt.ItemIsSelectable | PyQt5.QtCore.Qt.ItemIsEnabled | editable - - def rowCount(self, index): - if index.isValid(): - return 0 - return len(self.names) - - def columnCount(self, index): - return 2 - - def headerData(self, section, orientation, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - if section == 1: - return QVariant('Path') - return QVariant('Type') - - def index(self, row, column, parent): - return self.createIndex(row, column) - - def data(self, index, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - row = index.row() - column = index.column() - if column == 0: - return self.names[row] - return getattr(self.coredata, self.attr_name[row]) - - def parent(self, index): - return QModelIndex() - - def setData(self, index, value, role): - if role != PyQt5.QtCore.Qt.EditRole: - return False - row = index.row() - column = index.column() - s = str(value) - setattr(self.coredata, self.attr_name[row], s) - self.dataChanged.emit(self.createIndex(row, column), self.createIndex(row, column)) - return True - -class TargetModel(QAbstractItemModel): - def __init__(self, builddata): - super().__init__() - self.targets = [] - for target in builddata.get_targets().values(): - name = target.get_basename() - num_sources = len(target.get_sources()) + len(target.get_generated_sources()) - if isinstance(target, build.Executable): - typename = 'executable' - elif isinstance(target, build.SharedLibrary): - typename = 'shared library' - elif isinstance(target, build.StaticLibrary): - typename = 'static library' - elif isinstance(target, build.CustomTarget): - typename = 'custom' - else: - typename = 'unknown' - if target.should_install(): - installed = 'Yes' - else: - installed = 'No' - self.targets.append((name, typename, installed, num_sources)) - - def args(self, index): - return PyQt5.QtCore.Qt.ItemIsSelectable | PyQt5.QtCore.Qt.ItemIsEnabled - - def rowCount(self, index): - if index.isValid(): - return 0 - return len(self.targets) - - def columnCount(self, index): - return 4 - - def headerData(self, section, orientation, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - if section == 3: - return QVariant('Source files') - if section == 2: - return QVariant('Installed') - if section == 1: - return QVariant('Type') - return QVariant('Name') - - def data(self, index, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - row = index.row() - column = index.column() - return self.targets[row][column] - - def index(self, row, column, parent): - return self.createIndex(row, column) - - def parent(self, index): - return QModelIndex() - -class DependencyModel(QAbstractItemModel): - def __init__(self, coredata): - super().__init__() - self.deps = [] - for k in coredata.deps.keys(): - bd = coredata.deps[k] - name = k - found = bd.found() - if found: - cflags = str(bd.get_compile_args()) - libs = str(bd.get_link_args()) - found = 'yes' - else: - cflags = '' - libs = '' - found = 'no' - self.deps.append((name, found, cflags, libs)) - - def args(self, index): - return PyQt5.QtCore.Qt.ItemIsSelectable | PyQt5.QtCore.Qt.ItemIsEnabled - - def rowCount(self, index): - if index.isValid(): - return 0 - return len(self.deps) - - def columnCount(self, index): - return 4 - - def headerData(self, section, orientation, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - if section == 3: - return QVariant('Link args') - if section == 2: - return QVariant('Compile args') - if section == 1: - return QVariant('Found') - return QVariant('Name') - - def data(self, index, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - row = index.row() - column = index.column() - return self.deps[row][column] - - def index(self, row, column, parent): - return self.createIndex(row, column) - - def parent(self, index): - return QModelIndex() - -class CoreModel(QAbstractItemModel): - def __init__(self, core_data): - super().__init__() - self.elems = [] - for langname, comp in core_data.compilers.items(): - self.elems.append((langname + ' compiler', str(comp.get_exelist()))) - for langname, comp in core_data.cross_compilers.items(): - self.elems.append((langname + ' cross compiler', str(comp.get_exelist()))) - - def args(self, index): - return PyQt5.QtCore.Qt.ItemIsSelectable | PyQt5.QtCore.Qt.ItemIsEnabled - - def rowCount(self, index): - if index.isValid(): - return 0 - return len(self.elems) - - def columnCount(self, index): - return 2 - - def headerData(self, section, orientation, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - if section == 1: - return QVariant('Value') - return QVariant('Name') - - def data(self, index, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - row = index.row() - column = index.column() - return self.elems[row][column] - - def index(self, row, column, parent): - return self.createIndex(row, column) - - def parent(self, index): - return QModelIndex() - -class OptionForm: - def __init__(self, coredata, form): - self.coredata = coredata - self.form = form - form.addRow(PyQt5.QtWidgets.QLabel("Meson options")) - combo = QComboBox() - combo.addItem('plain') - combo.addItem('debug') - combo.addItem('debugoptimized') - combo.addItem('release') - combo.setCurrentText(self.coredata.buildtype) - combo.currentTextChanged.connect(self.build_type_changed) - self.form.addRow('Build type', combo) - strip = QCheckBox("") - strip.setChecked(self.coredata.strip) - strip.stateChanged.connect(self.strip_changed) - self.form.addRow('Strip on install', strip) - coverage = QCheckBox("") - coverage.setChecked(self.coredata.coverage) - coverage.stateChanged.connect(self.coverage_changed) - self.form.addRow('Enable coverage', coverage) - pch = QCheckBox("") - pch.setChecked(self.coredata.use_pch) - pch.stateChanged.connect(self.pch_changed) - self.form.addRow('Enable pch', pch) - unity = QCheckBox("") - unity.setChecked(self.coredata.unity) - unity.stateChanged.connect(self.unity_changed) - self.form.addRow('Unity build', unity) - form.addRow(PyQt5.QtWidgets.QLabel("Project options")) - self.set_user_options() - - def set_user_options(self): - options = self.coredata.user_options - keys = list(options.keys()) - keys.sort() - self.opt_keys = keys - self.opt_widgets = [] - for key in keys: - opt = options[key] - if isinstance(opt, mesonlib.UserStringOption): - w = PyQt5.QtWidgets.QLineEdit(opt.value) - w.textChanged.connect(self.user_option_changed) - elif isinstance(opt, mesonlib.UserBooleanOption): - w = QCheckBox('') - w.setChecked(opt.value) - w.stateChanged.connect(self.user_option_changed) - elif isinstance(opt, mesonlib.UserComboOption): - w = QComboBox() - for i in opt.choices: - w.addItem(i) - w.setCurrentText(opt.value) - w.currentTextChanged.connect(self.user_option_changed) - else: - raise RuntimeError("Unknown option type") - self.opt_widgets.append(w) - self.form.addRow(opt.description, w) - - def user_option_changed(self, dummy=None): - for i in range(len(self.opt_keys)): - key = self.opt_keys[i] - w = self.opt_widgets[i] - if isinstance(w, PyQt5.QtWidgets.QLineEdit): - newval = w.text() - elif isinstance(w, QComboBox): - newval = w.currentText() - elif isinstance(w, QCheckBox): - if w.checkState() == 0: - newval = False - else: - newval = True - else: - raise RuntimeError('Unknown widget type') - self.coredata.user_options[key].set_value(newval) - - def build_type_changed(self, newtype): - self.coredata.buildtype = newtype - - def strip_changed(self, newState): - if newState == 0: - ns = False - else: - ns = True - self.coredata.strip = ns - - def coverage_changed(self, newState): - if newState == 0: - ns = False - else: - ns = True - self.coredata.coverage = ns - - def pch_changed(self, newState): - if newState == 0: - ns = False - else: - ns = True - self.coredata.use_pch = ns - - def unity_changed(self, newState): - if newState == 0: - ns = False - else: - ns = True - self.coredata.unity = ns - -class ProcessRunner(): - def __init__(self, rundir, cmdlist): - self.cmdlist = cmdlist - self.ui = uic.loadUi(os.path.join(priv_dir, 'mesonrunner.ui')) - self.timer = QTimer(self.ui) - self.timer.setInterval(1000) - self.timer.timeout.connect(self.timeout) - self.process = PyQt5.QtCore.QProcess() - self.process.setProcessChannelMode(PyQt5.QtCore.QProcess.MergedChannels) - self.process.setWorkingDirectory(rundir) - self.process.readyRead.connect(self.read_data) - self.process.finished.connect(self.finished) - self.ui.termbutton.clicked.connect(self.terminated) - self.return_value = 100 - - def run(self): - self.process.start(self.cmdlist[0], self.cmdlist[1:]) - self.timer.start() - self.start_time = time.time() - return self.ui.exec() - - def read_data(self): - while(self.process.canReadLine()): - txt = bytes(self.process.readLine()).decode('utf8') - self.ui.console.append(txt) - - def finished(self): - self.read_data() - self.ui.termbutton.setText('Done') - self.timer.stop() - self.return_value = self.process.exitCode() - - def terminated(self, foo): - self.process.kill() - self.timer.stop() - self.ui.done(self.return_value) - - def timeout(self): - now = time.time() - duration = int(now - self.start_time) - msg = 'Elapsed time: %d:%d' % (duration // 60, duration % 60) - self.ui.timelabel.setText(msg) - -class MesonGui(): - def __init__(self, respawner, build_dir): - self.respawner = respawner - uifile = os.path.join(priv_dir, 'mesonmain.ui') - self.ui = uic.loadUi(uifile) - self.coredata_file = os.path.join(build_dir, 'meson-private/coredata.dat') - self.build_file = os.path.join(build_dir, 'meson-private/build.dat') - if not os.path.exists(self.coredata_file): - print("Argument is not build directory.") - sys.exit(1) - self.coredata = pickle.load(open(self.coredata_file, 'rb')) - self.build = pickle.load(open(self.build_file, 'rb')) - self.build_dir = self.build.environment.build_dir - self.src_dir = self.build.environment.source_dir - self.build_models() - self.options = OptionForm(self.coredata, self.ui.option_form) - self.ui.show() - - def hide(self): - self.ui.hide() - - def geometry(self): - return self.ui.geometry() - - def move(self, x, y): - return self.ui.move(x, y) - - def size(self): - return self.ui.size() - - def resize(self, s): - return self.ui.resize(s) - - def build_models(self): - self.path_model = PathModel(self.coredata) - self.target_model = TargetModel(self.build) - self.dep_model = DependencyModel(self.coredata) - self.core_model = CoreModel(self.coredata) - self.fill_data() - self.ui.core_view.setModel(self.core_model) - hv = QHeaderView(1) - hv.setModel(self.core_model) - self.ui.core_view.setHeader(hv) - self.ui.path_view.setModel(self.path_model) - hv = QHeaderView(1) - hv.setModel(self.path_model) - self.ui.path_view.setHeader(hv) - self.ui.target_view.setModel(self.target_model) - hv = QHeaderView(1) - hv.setModel(self.target_model) - self.ui.target_view.setHeader(hv) - self.ui.dep_view.setModel(self.dep_model) - hv = QHeaderView(1) - hv.setModel(self.dep_model) - self.ui.dep_view.setHeader(hv) - self.ui.compile_button.clicked.connect(self.compile) - self.ui.test_button.clicked.connect(self.run_tests) - self.ui.install_button.clicked.connect(self.install) - self.ui.clean_button.clicked.connect(self.clean) - self.ui.save_button.clicked.connect(self.save) - - def fill_data(self): - self.ui.project_label.setText(self.build.projects['']) - self.ui.srcdir_label.setText(self.src_dir) - self.ui.builddir_label.setText(self.build_dir) - if self.coredata.cross_file is None: - btype = 'Native build' - else: - btype = 'Cross build' - self.ui.buildtype_label.setText(btype) - - def run_process(self, cmdlist): - cmdlist = [shutil.which(environment.detect_ninja())] + cmdlist - dialog = ProcessRunner(self.build.environment.build_dir, cmdlist) - dialog.run() - # All processes (at the moment) may change cache state - # so reload. - self.respawner.respawn() - - def compile(self, foo): - self.run_process([]) - - def run_tests(self, foo): - self.run_process(['test']) - - def install(self, foo): - self.run_process(['install']) - - def clean(self, foo): - self.run_process(['clean']) - - def save(self, foo): - pickle.dump(self.coredata, open(self.coredata_file, 'wb')) - -class Starter(): - def __init__(self, sdir): - uifile = os.path.join(priv_dir, 'mesonstart.ui') - self.ui = uic.loadUi(uifile) - self.ui.source_entry.setText(sdir) - self.dialog = PyQt5.QtWidgets.QFileDialog() - if len(sdir) == 0: - self.dialog.setDirectory(os.getcwd()) - else: - self.dialog.setDirectory(sdir) - self.ui.source_browse_button.clicked.connect(self.src_browse_clicked) - self.ui.build_browse_button.clicked.connect(self.build_browse_clicked) - self.ui.cross_browse_button.clicked.connect(self.cross_browse_clicked) - self.ui.source_entry.textChanged.connect(self.update_button) - self.ui.build_entry.textChanged.connect(self.update_button) - self.ui.generate_button.clicked.connect(self.generate) - self.update_button() - self.ui.show() - - def generate(self): - srcdir = self.ui.source_entry.text() - builddir = self.ui.build_entry.text() - cross = self.ui.cross_entry.text() - cmdlist = [os.path.join(os.path.split(__file__)[0], 'meson.py'), srcdir, builddir] - if cross != '': - cmdlist += ['--cross', cross] - pr = ProcessRunner(os.getcwd(), cmdlist) - rvalue = pr.run() - if rvalue == 0: - os.execl(__file__, 'dummy', builddir) - - def update_button(self): - if self.ui.source_entry.text() == '' or self.ui.build_entry.text() == '': - self.ui.generate_button.setEnabled(False) - else: - self.ui.generate_button.setEnabled(True) - - def src_browse_clicked(self): - self.dialog.setFileMode(2) - if self.dialog.exec(): - self.ui.source_entry.setText(self.dialog.selectedFiles()[0]) - - def build_browse_clicked(self): - self.dialog.setFileMode(2) - if self.dialog.exec(): - self.ui.build_entry.setText(self.dialog.selectedFiles()[0]) - - def cross_browse_clicked(self): - self.dialog.setFileMode(1) - if self.dialog.exec(): - self.ui.cross_entry.setText(self.dialog.selectedFiles()[0]) - -# Rather than rewrite all classes and arrays to be -# updateable, just rebuild the entire GUI from -# scratch whenever data on disk changes. - -class MesonGuiRespawner(): - def __init__(self, arg): - self.arg = arg - self.gui = MesonGui(self, self.arg) - - def respawn(self): - geo = self.gui.geometry() - s = self.gui.size() - self.gui.hide() - self.gui = MesonGui(self, self.arg) - self.gui.move(geo.x(), geo.y()) - self.gui.resize(s) - # Garbage collection takes care of the old gui widget - -if __name__ == '__main__': - app = QApplication(sys.argv) - if len(sys.argv) == 1: - arg = "" - elif len(sys.argv) == 2: - arg = sys.argv[1] - else: - print(sys.argv[0], "") - sys.exit(1) - if os.path.exists(os.path.join(arg, 'meson-private/coredata.dat')): - guirespawner = MesonGuiRespawner(arg) - else: - runner = Starter(arg) - sys.exit(app.exec_()) -- cgit v1.1 From 66c01401deb186e6daa20cf4bf6a098076dda236 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Fri, 15 Jan 2016 23:37:22 +0200 Subject: Moved scripts in the module and started work to run them via the main meson command. --- mesongui.py | 561 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 561 insertions(+) create mode 100644 mesongui.py (limited to 'mesongui.py') diff --git a/mesongui.py b/mesongui.py new file mode 100644 index 0000000..bdd44bb --- /dev/null +++ b/mesongui.py @@ -0,0 +1,561 @@ +#!/usr/bin/env python3 + +# Copyright 2013-2015 The Meson development team + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys, os, pickle, time, shutil +import build, coredata, environment, mesonlib +from PyQt5 import uic +from PyQt5.QtWidgets import QApplication, QMainWindow, QHeaderView +from PyQt5.QtWidgets import QComboBox, QCheckBox +from PyQt5.QtCore import QAbstractItemModel, QModelIndex, QVariant, QTimer +import PyQt5.QtCore +import PyQt5.QtWidgets + +priv_dir = os.path.split(os.path.abspath(os.path.realpath(__file__)))[0] + +class PathModel(QAbstractItemModel): + def __init__(self, coredata): + super().__init__() + self.coredata = coredata + self.names = ['Prefix', 'Library dir', 'Binary dir', 'Include dir', 'Data dir',\ + 'Man dir', 'Locale dir'] + self.attr_name = ['prefix', 'libdir', 'bindir', 'includedir', 'datadir', \ + 'mandir', 'localedir'] + + def args(self, index): + if index.column() == 1: + editable = PyQt5.QtCore.Qt.ItemIsEditable + else: + editable= 0 + return PyQt5.QtCore.Qt.ItemIsSelectable | PyQt5.QtCore.Qt.ItemIsEnabled | editable + + def rowCount(self, index): + if index.isValid(): + return 0 + return len(self.names) + + def columnCount(self, index): + return 2 + + def headerData(self, section, orientation, role): + if role != PyQt5.QtCore.Qt.DisplayRole: + return QVariant() + if section == 1: + return QVariant('Path') + return QVariant('Type') + + def index(self, row, column, parent): + return self.createIndex(row, column) + + def data(self, index, role): + if role != PyQt5.QtCore.Qt.DisplayRole: + return QVariant() + row = index.row() + column = index.column() + if column == 0: + return self.names[row] + return getattr(self.coredata, self.attr_name[row]) + + def parent(self, index): + return QModelIndex() + + def setData(self, index, value, role): + if role != PyQt5.QtCore.Qt.EditRole: + return False + row = index.row() + column = index.column() + s = str(value) + setattr(self.coredata, self.attr_name[row], s) + self.dataChanged.emit(self.createIndex(row, column), self.createIndex(row, column)) + return True + +class TargetModel(QAbstractItemModel): + def __init__(self, builddata): + super().__init__() + self.targets = [] + for target in builddata.get_targets().values(): + name = target.get_basename() + num_sources = len(target.get_sources()) + len(target.get_generated_sources()) + if isinstance(target, build.Executable): + typename = 'executable' + elif isinstance(target, build.SharedLibrary): + typename = 'shared library' + elif isinstance(target, build.StaticLibrary): + typename = 'static library' + elif isinstance(target, build.CustomTarget): + typename = 'custom' + else: + typename = 'unknown' + if target.should_install(): + installed = 'Yes' + else: + installed = 'No' + self.targets.append((name, typename, installed, num_sources)) + + def args(self, index): + return PyQt5.QtCore.Qt.ItemIsSelectable | PyQt5.QtCore.Qt.ItemIsEnabled + + def rowCount(self, index): + if index.isValid(): + return 0 + return len(self.targets) + + def columnCount(self, index): + return 4 + + def headerData(self, section, orientation, role): + if role != PyQt5.QtCore.Qt.DisplayRole: + return QVariant() + if section == 3: + return QVariant('Source files') + if section == 2: + return QVariant('Installed') + if section == 1: + return QVariant('Type') + return QVariant('Name') + + def data(self, index, role): + if role != PyQt5.QtCore.Qt.DisplayRole: + return QVariant() + row = index.row() + column = index.column() + return self.targets[row][column] + + def index(self, row, column, parent): + return self.createIndex(row, column) + + def parent(self, index): + return QModelIndex() + +class DependencyModel(QAbstractItemModel): + def __init__(self, coredata): + super().__init__() + self.deps = [] + for k in coredata.deps.keys(): + bd = coredata.deps[k] + name = k + found = bd.found() + if found: + cflags = str(bd.get_compile_args()) + libs = str(bd.get_link_args()) + found = 'yes' + else: + cflags = '' + libs = '' + found = 'no' + self.deps.append((name, found, cflags, libs)) + + def args(self, index): + return PyQt5.QtCore.Qt.ItemIsSelectable | PyQt5.QtCore.Qt.ItemIsEnabled + + def rowCount(self, index): + if index.isValid(): + return 0 + return len(self.deps) + + def columnCount(self, index): + return 4 + + def headerData(self, section, orientation, role): + if role != PyQt5.QtCore.Qt.DisplayRole: + return QVariant() + if section == 3: + return QVariant('Link args') + if section == 2: + return QVariant('Compile args') + if section == 1: + return QVariant('Found') + return QVariant('Name') + + def data(self, index, role): + if role != PyQt5.QtCore.Qt.DisplayRole: + return QVariant() + row = index.row() + column = index.column() + return self.deps[row][column] + + def index(self, row, column, parent): + return self.createIndex(row, column) + + def parent(self, index): + return QModelIndex() + +class CoreModel(QAbstractItemModel): + def __init__(self, core_data): + super().__init__() + self.elems = [] + for langname, comp in core_data.compilers.items(): + self.elems.append((langname + ' compiler', str(comp.get_exelist()))) + for langname, comp in core_data.cross_compilers.items(): + self.elems.append((langname + ' cross compiler', str(comp.get_exelist()))) + + def args(self, index): + return PyQt5.QtCore.Qt.ItemIsSelectable | PyQt5.QtCore.Qt.ItemIsEnabled + + def rowCount(self, index): + if index.isValid(): + return 0 + return len(self.elems) + + def columnCount(self, index): + return 2 + + def headerData(self, section, orientation, role): + if role != PyQt5.QtCore.Qt.DisplayRole: + return QVariant() + if section == 1: + return QVariant('Value') + return QVariant('Name') + + def data(self, index, role): + if role != PyQt5.QtCore.Qt.DisplayRole: + return QVariant() + row = index.row() + column = index.column() + return self.elems[row][column] + + def index(self, row, column, parent): + return self.createIndex(row, column) + + def parent(self, index): + return QModelIndex() + +class OptionForm: + def __init__(self, coredata, form): + self.coredata = coredata + self.form = form + form.addRow(PyQt5.QtWidgets.QLabel("Meson options")) + combo = QComboBox() + combo.addItem('plain') + combo.addItem('debug') + combo.addItem('debugoptimized') + combo.addItem('release') + combo.setCurrentText(self.coredata.buildtype) + combo.currentTextChanged.connect(self.build_type_changed) + self.form.addRow('Build type', combo) + strip = QCheckBox("") + strip.setChecked(self.coredata.strip) + strip.stateChanged.connect(self.strip_changed) + self.form.addRow('Strip on install', strip) + coverage = QCheckBox("") + coverage.setChecked(self.coredata.coverage) + coverage.stateChanged.connect(self.coverage_changed) + self.form.addRow('Enable coverage', coverage) + pch = QCheckBox("") + pch.setChecked(self.coredata.use_pch) + pch.stateChanged.connect(self.pch_changed) + self.form.addRow('Enable pch', pch) + unity = QCheckBox("") + unity.setChecked(self.coredata.unity) + unity.stateChanged.connect(self.unity_changed) + self.form.addRow('Unity build', unity) + form.addRow(PyQt5.QtWidgets.QLabel("Project options")) + self.set_user_options() + + def set_user_options(self): + options = self.coredata.user_options + keys = list(options.keys()) + keys.sort() + self.opt_keys = keys + self.opt_widgets = [] + for key in keys: + opt = options[key] + if isinstance(opt, mesonlib.UserStringOption): + w = PyQt5.QtWidgets.QLineEdit(opt.value) + w.textChanged.connect(self.user_option_changed) + elif isinstance(opt, mesonlib.UserBooleanOption): + w = QCheckBox('') + w.setChecked(opt.value) + w.stateChanged.connect(self.user_option_changed) + elif isinstance(opt, mesonlib.UserComboOption): + w = QComboBox() + for i in opt.choices: + w.addItem(i) + w.setCurrentText(opt.value) + w.currentTextChanged.connect(self.user_option_changed) + else: + raise RuntimeError("Unknown option type") + self.opt_widgets.append(w) + self.form.addRow(opt.description, w) + + def user_option_changed(self, dummy=None): + for i in range(len(self.opt_keys)): + key = self.opt_keys[i] + w = self.opt_widgets[i] + if isinstance(w, PyQt5.QtWidgets.QLineEdit): + newval = w.text() + elif isinstance(w, QComboBox): + newval = w.currentText() + elif isinstance(w, QCheckBox): + if w.checkState() == 0: + newval = False + else: + newval = True + else: + raise RuntimeError('Unknown widget type') + self.coredata.user_options[key].set_value(newval) + + def build_type_changed(self, newtype): + self.coredata.buildtype = newtype + + def strip_changed(self, newState): + if newState == 0: + ns = False + else: + ns = True + self.coredata.strip = ns + + def coverage_changed(self, newState): + if newState == 0: + ns = False + else: + ns = True + self.coredata.coverage = ns + + def pch_changed(self, newState): + if newState == 0: + ns = False + else: + ns = True + self.coredata.use_pch = ns + + def unity_changed(self, newState): + if newState == 0: + ns = False + else: + ns = True + self.coredata.unity = ns + +class ProcessRunner(): + def __init__(self, rundir, cmdlist): + self.cmdlist = cmdlist + self.ui = uic.loadUi(os.path.join(priv_dir, 'mesonrunner.ui')) + self.timer = QTimer(self.ui) + self.timer.setInterval(1000) + self.timer.timeout.connect(self.timeout) + self.process = PyQt5.QtCore.QProcess() + self.process.setProcessChannelMode(PyQt5.QtCore.QProcess.MergedChannels) + self.process.setWorkingDirectory(rundir) + self.process.readyRead.connect(self.read_data) + self.process.finished.connect(self.finished) + self.ui.termbutton.clicked.connect(self.terminated) + self.return_value = 100 + + def run(self): + self.process.start(self.cmdlist[0], self.cmdlist[1:]) + self.timer.start() + self.start_time = time.time() + return self.ui.exec() + + def read_data(self): + while(self.process.canReadLine()): + txt = bytes(self.process.readLine()).decode('utf8') + self.ui.console.append(txt) + + def finished(self): + self.read_data() + self.ui.termbutton.setText('Done') + self.timer.stop() + self.return_value = self.process.exitCode() + + def terminated(self, foo): + self.process.kill() + self.timer.stop() + self.ui.done(self.return_value) + + def timeout(self): + now = time.time() + duration = int(now - self.start_time) + msg = 'Elapsed time: %d:%d' % (duration // 60, duration % 60) + self.ui.timelabel.setText(msg) + +class MesonGui(): + def __init__(self, respawner, build_dir): + self.respawner = respawner + uifile = os.path.join(priv_dir, 'mesonmain.ui') + self.ui = uic.loadUi(uifile) + self.coredata_file = os.path.join(build_dir, 'meson-private/coredata.dat') + self.build_file = os.path.join(build_dir, 'meson-private/build.dat') + if not os.path.exists(self.coredata_file): + print("Argument is not build directory.") + sys.exit(1) + self.coredata = pickle.load(open(self.coredata_file, 'rb')) + self.build = pickle.load(open(self.build_file, 'rb')) + self.build_dir = self.build.environment.build_dir + self.src_dir = self.build.environment.source_dir + self.build_models() + self.options = OptionForm(self.coredata, self.ui.option_form) + self.ui.show() + + def hide(self): + self.ui.hide() + + def geometry(self): + return self.ui.geometry() + + def move(self, x, y): + return self.ui.move(x, y) + + def size(self): + return self.ui.size() + + def resize(self, s): + return self.ui.resize(s) + + def build_models(self): + self.path_model = PathModel(self.coredata) + self.target_model = TargetModel(self.build) + self.dep_model = DependencyModel(self.coredata) + self.core_model = CoreModel(self.coredata) + self.fill_data() + self.ui.core_view.setModel(self.core_model) + hv = QHeaderView(1) + hv.setModel(self.core_model) + self.ui.core_view.setHeader(hv) + self.ui.path_view.setModel(self.path_model) + hv = QHeaderView(1) + hv.setModel(self.path_model) + self.ui.path_view.setHeader(hv) + self.ui.target_view.setModel(self.target_model) + hv = QHeaderView(1) + hv.setModel(self.target_model) + self.ui.target_view.setHeader(hv) + self.ui.dep_view.setModel(self.dep_model) + hv = QHeaderView(1) + hv.setModel(self.dep_model) + self.ui.dep_view.setHeader(hv) + self.ui.compile_button.clicked.connect(self.compile) + self.ui.test_button.clicked.connect(self.run_tests) + self.ui.install_button.clicked.connect(self.install) + self.ui.clean_button.clicked.connect(self.clean) + self.ui.save_button.clicked.connect(self.save) + + def fill_data(self): + self.ui.project_label.setText(self.build.projects['']) + self.ui.srcdir_label.setText(self.src_dir) + self.ui.builddir_label.setText(self.build_dir) + if self.coredata.cross_file is None: + btype = 'Native build' + else: + btype = 'Cross build' + self.ui.buildtype_label.setText(btype) + + def run_process(self, cmdlist): + cmdlist = [shutil.which(environment.detect_ninja())] + cmdlist + dialog = ProcessRunner(self.build.environment.build_dir, cmdlist) + dialog.run() + # All processes (at the moment) may change cache state + # so reload. + self.respawner.respawn() + + def compile(self, foo): + self.run_process([]) + + def run_tests(self, foo): + self.run_process(['test']) + + def install(self, foo): + self.run_process(['install']) + + def clean(self, foo): + self.run_process(['clean']) + + def save(self, foo): + pickle.dump(self.coredata, open(self.coredata_file, 'wb')) + +class Starter(): + def __init__(self, sdir): + uifile = os.path.join(priv_dir, 'mesonstart.ui') + self.ui = uic.loadUi(uifile) + self.ui.source_entry.setText(sdir) + self.dialog = PyQt5.QtWidgets.QFileDialog() + if len(sdir) == 0: + self.dialog.setDirectory(os.getcwd()) + else: + self.dialog.setDirectory(sdir) + self.ui.source_browse_button.clicked.connect(self.src_browse_clicked) + self.ui.build_browse_button.clicked.connect(self.build_browse_clicked) + self.ui.cross_browse_button.clicked.connect(self.cross_browse_clicked) + self.ui.source_entry.textChanged.connect(self.update_button) + self.ui.build_entry.textChanged.connect(self.update_button) + self.ui.generate_button.clicked.connect(self.generate) + self.update_button() + self.ui.show() + + def generate(self): + srcdir = self.ui.source_entry.text() + builddir = self.ui.build_entry.text() + cross = self.ui.cross_entry.text() + cmdlist = [os.path.join(os.path.split(__file__)[0], 'meson.py'), srcdir, builddir] + if cross != '': + cmdlist += ['--cross', cross] + pr = ProcessRunner(os.getcwd(), cmdlist) + rvalue = pr.run() + if rvalue == 0: + os.execl(__file__, 'dummy', builddir) + + def update_button(self): + if self.ui.source_entry.text() == '' or self.ui.build_entry.text() == '': + self.ui.generate_button.setEnabled(False) + else: + self.ui.generate_button.setEnabled(True) + + def src_browse_clicked(self): + self.dialog.setFileMode(2) + if self.dialog.exec(): + self.ui.source_entry.setText(self.dialog.selectedFiles()[0]) + + def build_browse_clicked(self): + self.dialog.setFileMode(2) + if self.dialog.exec(): + self.ui.build_entry.setText(self.dialog.selectedFiles()[0]) + + def cross_browse_clicked(self): + self.dialog.setFileMode(1) + if self.dialog.exec(): + self.ui.cross_entry.setText(self.dialog.selectedFiles()[0]) + +# Rather than rewrite all classes and arrays to be +# updateable, just rebuild the entire GUI from +# scratch whenever data on disk changes. + +class MesonGuiRespawner(): + def __init__(self, arg): + self.arg = arg + self.gui = MesonGui(self, self.arg) + + def respawn(self): + geo = self.gui.geometry() + s = self.gui.size() + self.gui.hide() + self.gui = MesonGui(self, self.arg) + self.gui.move(geo.x(), geo.y()) + self.gui.resize(s) + # Garbage collection takes care of the old gui widget + +if __name__ == '__main__': + app = QApplication(sys.argv) + if len(sys.argv) == 1: + arg = "" + elif len(sys.argv) == 2: + arg = sys.argv[1] + else: + print(sys.argv[0], "") + sys.exit(1) + if os.path.exists(os.path.join(arg, 'meson-private/coredata.dat')): + guirespawner = MesonGuiRespawner(arg) + else: + runner = Starter(arg) + sys.exit(app.exec_()) -- cgit v1.1 From 1510522b1b9970376a1e1cc5f39e00d8749ec19a Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sat, 16 Jan 2016 17:21:05 +0200 Subject: Moved mesongui into module. --- mesongui.py | 561 ------------------------------------------------------------ 1 file changed, 561 deletions(-) delete mode 100644 mesongui.py (limited to 'mesongui.py') diff --git a/mesongui.py b/mesongui.py deleted file mode 100644 index bdd44bb..0000000 --- a/mesongui.py +++ /dev/null @@ -1,561 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2013-2015 The Meson development team - -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at - -# http://www.apache.org/licenses/LICENSE-2.0 - -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import sys, os, pickle, time, shutil -import build, coredata, environment, mesonlib -from PyQt5 import uic -from PyQt5.QtWidgets import QApplication, QMainWindow, QHeaderView -from PyQt5.QtWidgets import QComboBox, QCheckBox -from PyQt5.QtCore import QAbstractItemModel, QModelIndex, QVariant, QTimer -import PyQt5.QtCore -import PyQt5.QtWidgets - -priv_dir = os.path.split(os.path.abspath(os.path.realpath(__file__)))[0] - -class PathModel(QAbstractItemModel): - def __init__(self, coredata): - super().__init__() - self.coredata = coredata - self.names = ['Prefix', 'Library dir', 'Binary dir', 'Include dir', 'Data dir',\ - 'Man dir', 'Locale dir'] - self.attr_name = ['prefix', 'libdir', 'bindir', 'includedir', 'datadir', \ - 'mandir', 'localedir'] - - def args(self, index): - if index.column() == 1: - editable = PyQt5.QtCore.Qt.ItemIsEditable - else: - editable= 0 - return PyQt5.QtCore.Qt.ItemIsSelectable | PyQt5.QtCore.Qt.ItemIsEnabled | editable - - def rowCount(self, index): - if index.isValid(): - return 0 - return len(self.names) - - def columnCount(self, index): - return 2 - - def headerData(self, section, orientation, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - if section == 1: - return QVariant('Path') - return QVariant('Type') - - def index(self, row, column, parent): - return self.createIndex(row, column) - - def data(self, index, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - row = index.row() - column = index.column() - if column == 0: - return self.names[row] - return getattr(self.coredata, self.attr_name[row]) - - def parent(self, index): - return QModelIndex() - - def setData(self, index, value, role): - if role != PyQt5.QtCore.Qt.EditRole: - return False - row = index.row() - column = index.column() - s = str(value) - setattr(self.coredata, self.attr_name[row], s) - self.dataChanged.emit(self.createIndex(row, column), self.createIndex(row, column)) - return True - -class TargetModel(QAbstractItemModel): - def __init__(self, builddata): - super().__init__() - self.targets = [] - for target in builddata.get_targets().values(): - name = target.get_basename() - num_sources = len(target.get_sources()) + len(target.get_generated_sources()) - if isinstance(target, build.Executable): - typename = 'executable' - elif isinstance(target, build.SharedLibrary): - typename = 'shared library' - elif isinstance(target, build.StaticLibrary): - typename = 'static library' - elif isinstance(target, build.CustomTarget): - typename = 'custom' - else: - typename = 'unknown' - if target.should_install(): - installed = 'Yes' - else: - installed = 'No' - self.targets.append((name, typename, installed, num_sources)) - - def args(self, index): - return PyQt5.QtCore.Qt.ItemIsSelectable | PyQt5.QtCore.Qt.ItemIsEnabled - - def rowCount(self, index): - if index.isValid(): - return 0 - return len(self.targets) - - def columnCount(self, index): - return 4 - - def headerData(self, section, orientation, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - if section == 3: - return QVariant('Source files') - if section == 2: - return QVariant('Installed') - if section == 1: - return QVariant('Type') - return QVariant('Name') - - def data(self, index, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - row = index.row() - column = index.column() - return self.targets[row][column] - - def index(self, row, column, parent): - return self.createIndex(row, column) - - def parent(self, index): - return QModelIndex() - -class DependencyModel(QAbstractItemModel): - def __init__(self, coredata): - super().__init__() - self.deps = [] - for k in coredata.deps.keys(): - bd = coredata.deps[k] - name = k - found = bd.found() - if found: - cflags = str(bd.get_compile_args()) - libs = str(bd.get_link_args()) - found = 'yes' - else: - cflags = '' - libs = '' - found = 'no' - self.deps.append((name, found, cflags, libs)) - - def args(self, index): - return PyQt5.QtCore.Qt.ItemIsSelectable | PyQt5.QtCore.Qt.ItemIsEnabled - - def rowCount(self, index): - if index.isValid(): - return 0 - return len(self.deps) - - def columnCount(self, index): - return 4 - - def headerData(self, section, orientation, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - if section == 3: - return QVariant('Link args') - if section == 2: - return QVariant('Compile args') - if section == 1: - return QVariant('Found') - return QVariant('Name') - - def data(self, index, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - row = index.row() - column = index.column() - return self.deps[row][column] - - def index(self, row, column, parent): - return self.createIndex(row, column) - - def parent(self, index): - return QModelIndex() - -class CoreModel(QAbstractItemModel): - def __init__(self, core_data): - super().__init__() - self.elems = [] - for langname, comp in core_data.compilers.items(): - self.elems.append((langname + ' compiler', str(comp.get_exelist()))) - for langname, comp in core_data.cross_compilers.items(): - self.elems.append((langname + ' cross compiler', str(comp.get_exelist()))) - - def args(self, index): - return PyQt5.QtCore.Qt.ItemIsSelectable | PyQt5.QtCore.Qt.ItemIsEnabled - - def rowCount(self, index): - if index.isValid(): - return 0 - return len(self.elems) - - def columnCount(self, index): - return 2 - - def headerData(self, section, orientation, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - if section == 1: - return QVariant('Value') - return QVariant('Name') - - def data(self, index, role): - if role != PyQt5.QtCore.Qt.DisplayRole: - return QVariant() - row = index.row() - column = index.column() - return self.elems[row][column] - - def index(self, row, column, parent): - return self.createIndex(row, column) - - def parent(self, index): - return QModelIndex() - -class OptionForm: - def __init__(self, coredata, form): - self.coredata = coredata - self.form = form - form.addRow(PyQt5.QtWidgets.QLabel("Meson options")) - combo = QComboBox() - combo.addItem('plain') - combo.addItem('debug') - combo.addItem('debugoptimized') - combo.addItem('release') - combo.setCurrentText(self.coredata.buildtype) - combo.currentTextChanged.connect(self.build_type_changed) - self.form.addRow('Build type', combo) - strip = QCheckBox("") - strip.setChecked(self.coredata.strip) - strip.stateChanged.connect(self.strip_changed) - self.form.addRow('Strip on install', strip) - coverage = QCheckBox("") - coverage.setChecked(self.coredata.coverage) - coverage.stateChanged.connect(self.coverage_changed) - self.form.addRow('Enable coverage', coverage) - pch = QCheckBox("") - pch.setChecked(self.coredata.use_pch) - pch.stateChanged.connect(self.pch_changed) - self.form.addRow('Enable pch', pch) - unity = QCheckBox("") - unity.setChecked(self.coredata.unity) - unity.stateChanged.connect(self.unity_changed) - self.form.addRow('Unity build', unity) - form.addRow(PyQt5.QtWidgets.QLabel("Project options")) - self.set_user_options() - - def set_user_options(self): - options = self.coredata.user_options - keys = list(options.keys()) - keys.sort() - self.opt_keys = keys - self.opt_widgets = [] - for key in keys: - opt = options[key] - if isinstance(opt, mesonlib.UserStringOption): - w = PyQt5.QtWidgets.QLineEdit(opt.value) - w.textChanged.connect(self.user_option_changed) - elif isinstance(opt, mesonlib.UserBooleanOption): - w = QCheckBox('') - w.setChecked(opt.value) - w.stateChanged.connect(self.user_option_changed) - elif isinstance(opt, mesonlib.UserComboOption): - w = QComboBox() - for i in opt.choices: - w.addItem(i) - w.setCurrentText(opt.value) - w.currentTextChanged.connect(self.user_option_changed) - else: - raise RuntimeError("Unknown option type") - self.opt_widgets.append(w) - self.form.addRow(opt.description, w) - - def user_option_changed(self, dummy=None): - for i in range(len(self.opt_keys)): - key = self.opt_keys[i] - w = self.opt_widgets[i] - if isinstance(w, PyQt5.QtWidgets.QLineEdit): - newval = w.text() - elif isinstance(w, QComboBox): - newval = w.currentText() - elif isinstance(w, QCheckBox): - if w.checkState() == 0: - newval = False - else: - newval = True - else: - raise RuntimeError('Unknown widget type') - self.coredata.user_options[key].set_value(newval) - - def build_type_changed(self, newtype): - self.coredata.buildtype = newtype - - def strip_changed(self, newState): - if newState == 0: - ns = False - else: - ns = True - self.coredata.strip = ns - - def coverage_changed(self, newState): - if newState == 0: - ns = False - else: - ns = True - self.coredata.coverage = ns - - def pch_changed(self, newState): - if newState == 0: - ns = False - else: - ns = True - self.coredata.use_pch = ns - - def unity_changed(self, newState): - if newState == 0: - ns = False - else: - ns = True - self.coredata.unity = ns - -class ProcessRunner(): - def __init__(self, rundir, cmdlist): - self.cmdlist = cmdlist - self.ui = uic.loadUi(os.path.join(priv_dir, 'mesonrunner.ui')) - self.timer = QTimer(self.ui) - self.timer.setInterval(1000) - self.timer.timeout.connect(self.timeout) - self.process = PyQt5.QtCore.QProcess() - self.process.setProcessChannelMode(PyQt5.QtCore.QProcess.MergedChannels) - self.process.setWorkingDirectory(rundir) - self.process.readyRead.connect(self.read_data) - self.process.finished.connect(self.finished) - self.ui.termbutton.clicked.connect(self.terminated) - self.return_value = 100 - - def run(self): - self.process.start(self.cmdlist[0], self.cmdlist[1:]) - self.timer.start() - self.start_time = time.time() - return self.ui.exec() - - def read_data(self): - while(self.process.canReadLine()): - txt = bytes(self.process.readLine()).decode('utf8') - self.ui.console.append(txt) - - def finished(self): - self.read_data() - self.ui.termbutton.setText('Done') - self.timer.stop() - self.return_value = self.process.exitCode() - - def terminated(self, foo): - self.process.kill() - self.timer.stop() - self.ui.done(self.return_value) - - def timeout(self): - now = time.time() - duration = int(now - self.start_time) - msg = 'Elapsed time: %d:%d' % (duration // 60, duration % 60) - self.ui.timelabel.setText(msg) - -class MesonGui(): - def __init__(self, respawner, build_dir): - self.respawner = respawner - uifile = os.path.join(priv_dir, 'mesonmain.ui') - self.ui = uic.loadUi(uifile) - self.coredata_file = os.path.join(build_dir, 'meson-private/coredata.dat') - self.build_file = os.path.join(build_dir, 'meson-private/build.dat') - if not os.path.exists(self.coredata_file): - print("Argument is not build directory.") - sys.exit(1) - self.coredata = pickle.load(open(self.coredata_file, 'rb')) - self.build = pickle.load(open(self.build_file, 'rb')) - self.build_dir = self.build.environment.build_dir - self.src_dir = self.build.environment.source_dir - self.build_models() - self.options = OptionForm(self.coredata, self.ui.option_form) - self.ui.show() - - def hide(self): - self.ui.hide() - - def geometry(self): - return self.ui.geometry() - - def move(self, x, y): - return self.ui.move(x, y) - - def size(self): - return self.ui.size() - - def resize(self, s): - return self.ui.resize(s) - - def build_models(self): - self.path_model = PathModel(self.coredata) - self.target_model = TargetModel(self.build) - self.dep_model = DependencyModel(self.coredata) - self.core_model = CoreModel(self.coredata) - self.fill_data() - self.ui.core_view.setModel(self.core_model) - hv = QHeaderView(1) - hv.setModel(self.core_model) - self.ui.core_view.setHeader(hv) - self.ui.path_view.setModel(self.path_model) - hv = QHeaderView(1) - hv.setModel(self.path_model) - self.ui.path_view.setHeader(hv) - self.ui.target_view.setModel(self.target_model) - hv = QHeaderView(1) - hv.setModel(self.target_model) - self.ui.target_view.setHeader(hv) - self.ui.dep_view.setModel(self.dep_model) - hv = QHeaderView(1) - hv.setModel(self.dep_model) - self.ui.dep_view.setHeader(hv) - self.ui.compile_button.clicked.connect(self.compile) - self.ui.test_button.clicked.connect(self.run_tests) - self.ui.install_button.clicked.connect(self.install) - self.ui.clean_button.clicked.connect(self.clean) - self.ui.save_button.clicked.connect(self.save) - - def fill_data(self): - self.ui.project_label.setText(self.build.projects['']) - self.ui.srcdir_label.setText(self.src_dir) - self.ui.builddir_label.setText(self.build_dir) - if self.coredata.cross_file is None: - btype = 'Native build' - else: - btype = 'Cross build' - self.ui.buildtype_label.setText(btype) - - def run_process(self, cmdlist): - cmdlist = [shutil.which(environment.detect_ninja())] + cmdlist - dialog = ProcessRunner(self.build.environment.build_dir, cmdlist) - dialog.run() - # All processes (at the moment) may change cache state - # so reload. - self.respawner.respawn() - - def compile(self, foo): - self.run_process([]) - - def run_tests(self, foo): - self.run_process(['test']) - - def install(self, foo): - self.run_process(['install']) - - def clean(self, foo): - self.run_process(['clean']) - - def save(self, foo): - pickle.dump(self.coredata, open(self.coredata_file, 'wb')) - -class Starter(): - def __init__(self, sdir): - uifile = os.path.join(priv_dir, 'mesonstart.ui') - self.ui = uic.loadUi(uifile) - self.ui.source_entry.setText(sdir) - self.dialog = PyQt5.QtWidgets.QFileDialog() - if len(sdir) == 0: - self.dialog.setDirectory(os.getcwd()) - else: - self.dialog.setDirectory(sdir) - self.ui.source_browse_button.clicked.connect(self.src_browse_clicked) - self.ui.build_browse_button.clicked.connect(self.build_browse_clicked) - self.ui.cross_browse_button.clicked.connect(self.cross_browse_clicked) - self.ui.source_entry.textChanged.connect(self.update_button) - self.ui.build_entry.textChanged.connect(self.update_button) - self.ui.generate_button.clicked.connect(self.generate) - self.update_button() - self.ui.show() - - def generate(self): - srcdir = self.ui.source_entry.text() - builddir = self.ui.build_entry.text() - cross = self.ui.cross_entry.text() - cmdlist = [os.path.join(os.path.split(__file__)[0], 'meson.py'), srcdir, builddir] - if cross != '': - cmdlist += ['--cross', cross] - pr = ProcessRunner(os.getcwd(), cmdlist) - rvalue = pr.run() - if rvalue == 0: - os.execl(__file__, 'dummy', builddir) - - def update_button(self): - if self.ui.source_entry.text() == '' or self.ui.build_entry.text() == '': - self.ui.generate_button.setEnabled(False) - else: - self.ui.generate_button.setEnabled(True) - - def src_browse_clicked(self): - self.dialog.setFileMode(2) - if self.dialog.exec(): - self.ui.source_entry.setText(self.dialog.selectedFiles()[0]) - - def build_browse_clicked(self): - self.dialog.setFileMode(2) - if self.dialog.exec(): - self.ui.build_entry.setText(self.dialog.selectedFiles()[0]) - - def cross_browse_clicked(self): - self.dialog.setFileMode(1) - if self.dialog.exec(): - self.ui.cross_entry.setText(self.dialog.selectedFiles()[0]) - -# Rather than rewrite all classes and arrays to be -# updateable, just rebuild the entire GUI from -# scratch whenever data on disk changes. - -class MesonGuiRespawner(): - def __init__(self, arg): - self.arg = arg - self.gui = MesonGui(self, self.arg) - - def respawn(self): - geo = self.gui.geometry() - s = self.gui.size() - self.gui.hide() - self.gui = MesonGui(self, self.arg) - self.gui.move(geo.x(), geo.y()) - self.gui.resize(s) - # Garbage collection takes care of the old gui widget - -if __name__ == '__main__': - app = QApplication(sys.argv) - if len(sys.argv) == 1: - arg = "" - elif len(sys.argv) == 2: - arg = sys.argv[1] - else: - print(sys.argv[0], "") - sys.exit(1) - if os.path.exists(os.path.join(arg, 'meson-private/coredata.dat')): - guirespawner = MesonGuiRespawner(arg) - else: - runner = Starter(arg) - sys.exit(app.exec_()) -- cgit v1.1