Esempio n. 1
0
class MainWindow(QMainWindow):

    def __init__(self, parallel=False, parent=None):
        super(MainWindow, self).__init__(parent)

        self.showMaximized()

        self.setWindowTitle("Poropy PWR Core Optimization Interface")

        self.model = Model()
        
        self.data = []
        self.dataPeak = []

        # Add menu items

        self.menubar = QMenuBar(self)

        self.menuFile = QMenu("&File", self.menubar)
        self.actionBuild = QAction("Build &Core", self)
        self.actionBuild.triggered.connect(self.build_core)
        self.actionSaveImg = QAction("Save Core &Image", self)
        self.actionSaveImg.triggered.connect(self.save_img)
        self.actionExit = QAction("E&xit", self)
        self.actionExit.triggered.connect(self.close)
        self.menuFile.addActions([self.actionBuild, self.actionSaveImg, self.actionExit])
        self.menuFile.insertSeparator(self.actionExit)

        self.menuSettings = QMenu("&Settings", self.menubar)
        self.actionEval = QAction("&Evaluator Settings", self)
        self.actionEval.triggered.connect(self.evaluator_settings)
        self.actionObjective = QAction("&Objective Settings", self)
        self.actionObjective.triggered.connect(self.objective_settings)
        self.actionCore = QAction("&Core Display Settings", self)
        self.actionCore.triggered.connect(self.core_display_settings)
        self.menuSettings.addActions([self.actionEval, self.actionObjective, self.actionCore])

        self.menuTools = QMenu("&Tools", self.menubar)
        self.actionOptimize = QAction("&Run Optimization", self)
        self.actionOptimize.triggered.connect(self.run_optimization)
        self.menuTools.addActions([self.actionOptimize])

        self.menuHelp = QMenu("&Help", self.menubar)
        self.actionAbout = QAction("&About", self)
        self.actionAbout.triggered.connect(self.about)
        self.menuHelp.addActions([self.actionAbout])

        self.menubar.addActions([self.menuFile.menuAction(),
                                 self.menuSettings.menuAction(),
                                 self.menuTools.menuAction(),
                                 self.menuHelp.menuAction()])
        self.setMenuBar(self.menubar)

        # Instantiate widgets

        self.coreDisplay = widgets.CoreDisplay()
        self.coreDisplay.updateSignal.connect(self.update)
        self.plotObjective = Chart([0, 1, 0, 100], [0], self, legend=None, xlabel=None, ylabel=None, temp=False)
        self.plotKeff = Chart([0, 1, 0, 2], [0], self, legend=None, xlabel=None, ylabel=None, temp=False)
        self.plotPeaking = Chart([0, 1, 0, 100], [0], self, legend=None, xlabel=None, ylabel=None, temp=False)
        self.allPatterns = widgets.PatternList()
        self.savedPatterns = widgets.PatternList()
        self.logView = widgets.LogWatcher("output.log")

        # Setup widget layouts

        self.plotKeff.setMinimumSize(400, 400)
        rightLayout = QHBoxLayout()
        tabsPlot = QTabWidget()
        tabsPlot.addTab(self.plotKeff, "keff")
        tabsPlot.addTab(self.plotPeaking, "Max Peaking")
        tabsPlot.addTab(self.plotObjective, "Objective")

        tabsPatt = QTabWidget()
        tabsPatt.addTab(self.allPatterns, "Previous Patterns")
#        tabsPatt.addTab(self.savedPatterns, "Saved Patterns")

        outerHorSplit = QSplitter()
        leftVertSplit = QSplitter()
        rightVertSplit = QSplitter()
        leftVertSplit.setOrientation(Qt.Vertical)
        rightVertSplit.setOrientation(Qt.Vertical)

        self.coreDisplay.setMinimumSize(600, 500)
        leftVertSplit.addWidget(self.coreDisplay)
        leftVertSplit.addWidget(self.logView)

        rightVertSplit.addWidget(tabsPlot)
        rightVertSplit.addWidget(tabsPatt)

        outerHorSplit.addWidget(leftVertSplit)
        outerHorSplit.addWidget(rightVertSplit)
        self.setCentralWidget(outerHorSplit)

        # this file is the controller, which handles the interplay between the
        # model and the views
        # connections to the views

        # connections to the model
        
################################################################################
#  Menu Slots
################################################################################

    def build_core(self):
      file = QFileDialog.getOpenFileName(self, 'Open File', '$home')
      path = file[0].split("/")
      file = path[-1]
      path = '/'.join(path[:-1])
      sys.path.append(path)
      #os.path.join(os.path.join(path, "plugins"), "reactor")
      #pluginDir = os.path.join(os.path.join(sys.path[0], "plugins"), "reactor")
      form = PluginControl(self.model, file, self)
      form.set_help("""<html>
<head>
<title>       </title>
<style type="text/css">
<!--
h1	{text-align:center;
	font-family:Arial, Helvetica, Sans-Serif;
	}

p	{text-indent:20px;
	}
-->
</style>
</head>
<body bgcolor = "#ffffcc" text = "#000000">
<h1>Hello, World!</h1>

<p>All of these descriptions are fed to a QTextEdit
(http://qt-project.org/doc/qt-4.8/qtextedit.html#setText), which supports some
simple HTML and CSS.</p>

</body>
</html>""")
      #form.show()
      
      self.reactor_data = form.data()
      self.new_reactor()
          
    def save_img(self):
      filename = QFileDialog.getSaveFileName(self, "Save Core Image", "./",
                                               "PNG Files (*.png)")
      if filename:
        if not str(filename[-4:]).lower() == '.png':
          filename = str(filename) + ".png"
        #self.coreDisplay.save_image(filename)
    
    def evaluator_settings(self):
      pluginDir = os.path.join(os.path.join(sys.path[0], "plugins"), "evaluator")
      form = PluginControl(self.model, pluginDir, self)
      form.set_help("""Evaluator Settings Help""")
      form.show()
      
    def objective_settings(self):
      pluginDir = os.path.join(os.path.join(sys.path[0], "plugins"), "objective")
      form = PluginControl(self.model, pluginDir, self)
      form.set_help("""Evaluator Settings Help""")
      form.show()
    
    def core_display_settings(self):
    
      choices = ["Burnup", "Enrichment", "Power Peaking", "K-Infinity"]
      choice, ok = QInputDialog.getItem(self, "Core Display Coloring",
                                       "Choose how to display core",
                                       choices, 0, False)
#       if ok:
#         if choice == "Burnup":
#           self.coreDisplay.set_coloring(widgets.CoreDisplay.COLOR_BURNUP)
#         elif choice == "Enrichment":
#           self.coreDisplay.set_coloring(widgets.CoreDisplay.COLOR_ENRICHMENT)
#         elif choice == "Power Peaking":
#           self.coreDisplay.set_coloring(widgets.CoreDisplay.COLOR_POWER)
#         elif choice == "K-Infinity":
#           self.coreDisplay.set_coloring(widgets.CoreDisplay.COLOR_KINF)
#         self.coreDisplay.pattern_updated()

    def run_optimization(self):
      pluginDir = os.path.join(os.path.join(sys.path[0], "plugins"), "optimizer")
      form = PluginControl(self.model, pluginDir, self)
      form.set_help("""Optimizer Help""")
      form.show()

################################################################################
#  View Slots - for views that need to interact with the model
################################################################################

    def assembly_swap(self, toFrom):
        """Slot called on manual swap from the core display widget"""
        self.model.swap_assemblies(toFrom[0], toFrom[1])
        self.model.evaluate_reactor()

    def change_pattern(self, index):
        """Slot for when a pattern list item is clicked"""
        
        if isinstance(index, QVariant):
            index = index.toPyObject()

        self.model.change_to_pattern(index)

################################################################################
#  Model Slots - for updating views when the model changes
################################################################################

    def new_reactor(self):
      """Do a full reset on the gui with a new starting core pattern"""
      self.data.append(self.reactor_data.solver.cycle_keff()[0])
      self.power = self.get_appf(self.reactor_data.solver.assembly_powers())
      self.maxPeak = max(self.power)/(sum(self.power)/len(self.power))
      self.dataPeak.append(self.maxPeak)
      time = QTime.currentTime()
      time = time.toString(Qt.DefaultLocaleLongDate)
      
      # TODO: Make sure this works self.reactor_data.core
      # TODO: Delete duplicate data (stencil vs core)
      self.coreDisplay.build(self.reactor_data.stencil, self.reactor_data.bu, self.reactor_data.core, self.reactor_data.solver)
      self.plotKeff.updateFigure(self.data)
      self.allPatterns.add_pattern(time, 0, self.coreDisplay.pattern, self.reactor_data.solver.cycle_keff()[0], self.maxPeak, 0)

    def new_evaluation(self):
      """Update the pattern list, the plots, and any printouts with the new data"""

      i, latest = self.model.get_latest_pattern()
      
      self.allPatterns.add_pattern(i,
                                    latest['timestamp'],
                                    latest['pattern'],
                                    latest['keff'],
                                    latest['maxpeak'],
                                    latest['objective'])
      
      self.plotPeaking.add_point(latest['maxpeak'])
      self.plotKeff.add_point(latest['keff'])
      self.plotObjective.add_point(latest['objective'])

    def pattern_changed(self):
        """Slot called whenever the current pattern of the Reactor is changed"""
        
        self.coreDisplay.pattern_updated()
        i = self.model.get_current_pattern_index()

        self.plotKeff.move_selection(i)
        self.plotPeaking.move_selection(i)
        self.plotObjective.move_selection(i)

    def about(self):
        QMessageBox.about(self, "About Poropy PWR Core Optimization Interface",
                          """<b>Py-Image PWR Core Optimization Interface</b> v %s
                          <p>Copyright &copy; 2012 Nick Horelik, Jeremy Roberts, 
                          All Rights Reserved.
                          <p>Python %s -- Qt %s -- PyQt %s on %s""" % 
                          (__version__, platform.python_version(),
                           QT_VERSION_STR, PYQT_VERSION_STR, platform.system()))
        
    def update(self):
        super(MainWindow, self).update()
        self.solver = self.reactor_data.initialize()
        self.solver.solve()
        self.plotKeff.updateFigure(self.data)
        self.data.append(self.solver.cycle_keff()[0])
        self.power = self.get_appf(self.solver.assembly_powers())
        self.maxPeak = max(self.power)/(sum(self.power)/len(self.power))
        self.plotPeaking.updateFigure(self.dataPeak)
        self.dataPeak.append(self.maxPeak)
        time = QTime.currentTime()
        time = time.toString(Qt.DefaultLocaleLongDate)
        self.allPatterns.add_pattern(time, 0, self.coreDisplay.pattern, self.solver.cycle_keff()[0], self.maxPeak, 0)
        
    def get_appf(self, p):
        appf = np.array(p)
        return list(appf / np.mean(appf))
Esempio n. 2
0
class MainWindowUi(QMainWindow):
    """Main Window"""
    def __init__(self, lang, translator):
        super().__init__()
        # Init
        self.lang = lang
        self._translateanslator = translator
        self._translate = QApplication.translate
        self.window_body = QWidget(self)
        self.process_type = QGroupBox(self.window_body)
        self.btn_fw = QRadioButton(self.process_type)
        self.btn_nonarb = QRadioButton(self.process_type)
        self.btn_vendor = QRadioButton(self.process_type)
        self.btn_fwless = QRadioButton(self.process_type)
        self.frame = QFrame(self.window_body)
        self.btn_select = QPushButton(self.frame)
        self.btn_url = QPushButton(self.frame)
        self.btn_create = QPushButton(self.frame)
        self.menubar = QMenuBar(self)
        self.status_box = QTextEdit(self.window_body)
        self.groupbox_drop = DropSpace(self.window_body, self.status_box,
                                       self._translate)
        self.label_drop = QLabel(self.groupbox_drop)
        self.progress_bar = QProgressBar(self.window_body)
        self.menu_file = QMenu(self.menubar)
        self.statusbar = QStatusBar(self)
        self.menu_language = QMenu(self.menubar)
        self.menu_help = QMenu(self.menubar)
        self.action_open_zip = QAction(self)
        self.action_open_remote_zip = QAction(self)
        self.action_quit = QAction(self)
        # languages
        self.action_language_sq = QAction(self)
        self.action_language_ar = QAction(self)
        self.action_language_ca = QAction(self)
        self.action_language_zh_CN = QAction(self)
        self.action_language_hr = QAction(self)
        self.action_language_cs = QAction(self)
        self.action_language_nl = QAction(self)
        self.action_language_en = QAction(self)
        self.action_language_fr = QAction(self)
        self.action_language_de = QAction(self)
        self.action_language_el = QAction(self)
        self.action_language_hi = QAction(self)
        self.action_language_id = QAction(self)
        self.action_language_it = QAction(self)
        self.action_language_fa = QAction(self)
        self.action_language_ms = QAction(self)
        self.action_language_pl = QAction(self)
        self.action_language_pt_BR = QAction(self)
        self.action_language_ro = QAction(self)
        self.action_language_ru = QAction(self)
        self.action_language_sl = QAction(self)
        self.action_language_es_ES = QAction(self)
        self.action_language_tr = QAction(self)
        self.action_language_uk = QAction(self)
        self.action_language_vi = QAction(self)
        self.action_donate = QAction(self)
        self.action_about = QAction(self)
        self.action_report_bug = QAction(self)
        self.action_website = QAction(self)
        # vars
        self.filepath = None
        self.filename = ''
        # setup
        self.setup_ui()
        self.setWindowIcon(QIcon(f'{current_dir}/icon.png'))
        self.center()
        adjust_layout_direction(self, lang)
        self.show()

    def setup_ui(self):
        """
        setup window ui
        """
        # Main Window
        self.setObjectName("main_window")
        self.setEnabled(True)
        self.resize(600, 400)
        size_policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        size_policy.setHorizontalStretch(0)
        size_policy.setVerticalStretch(0)
        size_policy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(size_policy)
        self.setMinimumSize(QSize(600, 400))
        self.setMaximumSize(QSize(600, 400))
        self.window_body.setObjectName("window_body")
        self.setCentralWidget(self.window_body)
        # GroupBox: process_type
        self.process_choose()
        # GroupBox: Drop files
        self.file_dropper()
        # Frame: Status
        self.status_frame()
        # Menubar
        self.menu_bar()
        # UI Strings
        self.re_translate_ui()
        QMetaObject.connectSlotsByName(self)

    def process_choose(self):
        """
        GroupBox: process_type
        """
        self.process_type.setGeometry(QRect(10, 20, 250, 140))
        self.process_type.setObjectName("process_type")
        self.btn_fw.setGeometry(QRect(10, 20, 160, 30))
        self.btn_fw.setObjectName("btn_fw")
        self.btn_nonarb.setGeometry(QRect(10, 50, 160, 30))
        self.btn_nonarb.setObjectName("btn_nonarb")
        self.btn_vendor.setGeometry(QRect(10, 80, 160, 30))
        self.btn_vendor.setObjectName("btn_vendor")
        self.btn_fwless.setGeometry(QRect(10, 110, 160, 30))
        self.btn_fwless.setObjectName("btn_fwless")
        # Actions
        self.btn_fw.setChecked(True)

    def file_dropper(self):
        """
        GroupBox: Drop files
        """
        self.groupbox_drop.setGeometry(QRect(270, 20, 320, 140))
        self.groupbox_drop.setObjectName("groupbox_drop")
        self.groupbox_drop.setAcceptDrops(True)
        self.label_drop.setGeometry(QRect(0, 30, 320, 111))
        # self.label_drop.setFrameShape(QFrame.Box)
        # self.label_drop.setFrameShadow(QFrame.Sunken)
        # self.label_drop.setLineWidth(2)
        self.label_drop.setAlignment(Qt.AlignCenter)
        self.label_drop.setObjectName("label_drop")

    def status_frame(self):
        """
        Frame: Status
        """
        self.frame.setGeometry(QRect(10, 170, 580, 80))
        self.frame.setFrameShape(QFrame.StyledPanel)
        self.frame.setFrameShadow(QFrame.Raised)
        self.frame.setObjectName("frame")
        self.btn_select.setGeometry(QRect(125, 20, 105, 35))
        self.btn_select.setObjectName("btn_select")
        self.btn_select.setStatusTip("action_open_zip_tip")
        self.btn_url.setGeometry(QRect(240, 20, 105, 35))
        self.btn_url.setObjectName("btn_url")
        self.btn_url.setStatusTip("action_zip_url_tip")
        self.btn_create.setGeometry(QRect(355, 20, 105, 35))
        self.btn_create.setObjectName("btn_create")
        self.btn_create.setStatusTip("btn_create_tip")
        self.status_box.setGeometry(QRect(10, 250, 580, 40))
        self.status_box.setObjectName("status_box")
        # self.status_box.setFrameShape(QFrame.Box)
        # self.status_box.setFrameShadow(QFrame.Sunken)
        self.status_box.setReadOnly(True)
        self.status_box.setOverwriteMode(True)
        self.status_box.setObjectName("status_box")
        self.progress_bar.setGeometry(QRect(10, 300, 580, 40))
        self.progress_bar.setObjectName("progress_bar")
        self.progress_bar.setValue(0)

        # Action
        self.btn_select.clicked.connect(self.select_file)
        self.btn_url.clicked.connect(self.enter_url)
        self.btn_create.clicked.connect(self.create_zip)

    def menu_bar(self):
        """
        Menubar
        """
        self.menubar.setGeometry(QRect(0, 0, 600, 32))
        self.menubar.setObjectName("menubar")
        self.menu_file.setObjectName("menu_file")
        self.menu_language.setObjectName("menu_language")
        self.menu_help.setObjectName("menu_help")
        self.setMenuBar(self.menubar)
        self.statusbar.setObjectName("statusbar")
        self.setStatusBar(self.statusbar)
        self.action_open_zip.setObjectName("action_open_zip")
        self.action_open_zip.setStatusTip("action_open_zip_tip")
        self.action_open_remote_zip.setObjectName("action_open_remote_zip")
        self.action_open_remote_zip.setStatusTip("action_open_remote_zip")
        self.action_quit.setObjectName("action_quit")
        self.action_quit.setStatusTip("action_quit_tip")
        self.action_language_sq.setObjectName("action_language_sq")
        self.action_language_ar.setObjectName("action_language_ar")
        self.action_language_ca.setObjectName("action_language_ca")
        self.action_language_zh_CN.setObjectName("action_language_zh_CN")
        self.action_language_hr.setObjectName("action_language_hr")
        self.action_language_cs.setObjectName("action_language_cs")
        self.action_language_nl.setObjectName("action_language_nl")
        self.action_language_en.setObjectName("action_language_en")
        self.action_language_fr.setObjectName("action_language_fr")
        self.action_language_de.setObjectName("action_language_de")
        self.action_language_el.setObjectName("action_language_el")
        self.action_language_hi.setObjectName("action_language_hi")
        self.action_language_id.setObjectName("action_language_id")
        self.action_language_it.setObjectName("action_language_it")
        self.action_language_ms.setObjectName("action_language_ms")
        self.action_language_fa.setObjectName("action_language_fa")
        self.action_language_pl.setObjectName("action_language_pl")
        self.action_language_pt_BR.setObjectName("action_language_pt_BR")
        self.action_language_ro.setObjectName("action_language_ro")
        self.action_language_ru.setObjectName("action_language_ru")
        self.action_language_sl.setObjectName("action_language_sl")
        self.action_language_es_ES.setObjectName("action_language_es_ES")
        self.action_language_tr.setObjectName("action_language_tr")
        self.action_language_uk.setObjectName("action_language_uk")
        self.action_language_vi.setObjectName("action_language_vi")
        self.action_report_bug.setObjectName("action_report_bug")
        self.action_report_bug.setStatusTip("action_report_bug_tip")
        self.action_donate.setObjectName("action_donate")
        self.action_donate.setStatusTip("action_donate_tip")
        self.action_about.setObjectName("action_about")
        self.action_about.setStatusTip("action_about_tip")
        self.action_website.setObjectName("action_website")
        self.action_website.setStatusTip("action_website_tip")
        self.menu_file.addActions([
            self.action_open_zip, self.action_open_remote_zip, self.action_quit
        ])
        self.menu_language.addActions([
            self.action_language_sq, self.action_language_ar,
            self.action_language_ca, self.action_language_zh_CN,
            self.action_language_hr, self.action_language_cs,
            self.action_language_nl, self.action_language_en,
            self.action_language_fr, self.action_language_de,
            self.action_language_el, self.action_language_hi,
            self.action_language_id, self.action_language_it,
            self.action_language_ms, self.action_language_fa,
            self.action_language_pl, self.action_language_pt_BR,
            self.action_language_ro, self.action_language_ru,
            self.action_language_sl, self.action_language_es_ES,
            self.action_language_tr, self.action_language_uk,
            self.action_language_vi
        ])
        self.menu_help.addActions([
            self.action_report_bug, self.action_donate, self.action_about,
            self.action_website
        ])
        self.menubar.addActions([
            self.menu_file.menuAction(),
            self.menu_language.menuAction(),
            self.menu_help.menuAction()
        ])
        # Shortcuts
        self.action_open_zip.setShortcut('Ctrl+O')
        self.action_open_remote_zip.setShortcut('Ctrl+R')
        self.action_quit.setShortcut('Ctrl+Q')
        # Actions
        self.action_open_zip.triggered.connect(self.select_file)
        self.action_open_remote_zip.triggered.connect(self.enter_url)
        self.action_quit.triggered.connect(qApp.quit)
        self.action_language_sq.triggered.connect(
            lambda: self.change_language("sq"))
        self.action_language_ar.triggered.connect(
            lambda: self.change_language("ar"))
        self.action_language_ca.triggered.connect(
            lambda: self.change_language("ca"))
        self.action_language_zh_CN.triggered.connect(
            lambda: self.change_language("zh-CN"))
        self.action_language_hr.triggered.connect(
            lambda: self.change_language("hr"))
        self.action_language_cs.triggered.connect(
            lambda: self.change_language("cs"))
        self.action_language_nl.triggered.connect(
            lambda: self.change_language("nl"))
        self.action_language_en.triggered.connect(
            lambda: self.change_language("en_US"))
        self.action_language_fr.triggered.connect(
            lambda: self.change_language("fr"))
        self.action_language_de.triggered.connect(
            lambda: self.change_language("de"))
        self.action_language_el.triggered.connect(
            lambda: self.change_language("el"))
        self.action_language_hi.triggered.connect(
            lambda: self.change_language("hi"))
        self.action_language_id.triggered.connect(
            lambda: self.change_language("id"))
        self.action_language_it.triggered.connect(
            lambda: self.change_language("it"))
        self.action_language_ms.triggered.connect(
            lambda: self.change_language("ms"))
        self.action_language_fa.triggered.connect(
            lambda: self.change_language("fa"))
        self.action_language_pl.triggered.connect(
            lambda: self.change_language("pl"))
        self.action_language_pt_BR.triggered.connect(
            lambda: self.change_language("pt-BR"))
        self.action_language_ro.triggered.connect(
            lambda: self.change_language("ro"))
        self.action_language_ru.triggered.connect(
            lambda: self.change_language("ru"))
        self.action_language_sl.triggered.connect(
            lambda: self.change_language("sl"))
        self.action_language_es_ES.triggered.connect(
            lambda: self.change_language("es-ES"))
        self.action_language_tr.triggered.connect(
            lambda: self.change_language("tr"))
        self.action_language_uk.triggered.connect(
            lambda: self.change_language("uk"))
        self.action_language_vi.triggered.connect(
            lambda: self.change_language("vi"))
        self.action_about.triggered.connect(self.open_about)
        self.action_report_bug.triggered.connect(lambda: self.open_link(
            'https://github.com/XiaomiFirmwareUpdater/'
            'xiaomi-flashable-firmware-creator-gui/issues'))
        self.action_donate.triggered.connect(
            lambda: self.open_link('https://xiaomifirmwareupdater.com/donate'))
        self.action_website.triggered.connect(
            lambda: self.open_link('https://xiaomifirmwareupdater.com'))

    def re_translate_ui(self):
        """
        Items strings
        """
        self.setWindowTitle(
            self._translate("Title", "Xiaomi Flashable Firmware Creator"))
        self.process_type.setTitle(self._translate("Radio Buttons", "Process"))
        self.btn_fw.setText(self._translate("Radio Buttons", "Firmware"))
        self.btn_nonarb.setText(
            self._translate("Radio Buttons", "Non-ARB Firmware"))
        self.btn_vendor.setText(
            self._translate("Radio Buttons", "Firmware + Vendor"))
        self.btn_fwless.setText(
            self._translate("Radio Buttons", "Firmware-less ROM"))
        self.groupbox_drop.setTitle(
            self._translate("Drop space", "Drop a file"))
        self.label_drop.setText(
            self._translate(
                "Drop space", "<html><head/><body>"
                "<p align=\"center\">"
                "<span style=\" font-style:italic;\">"
                "Drop a rom zip file here"
                "</span></p></body></html>"))
        self.btn_select.setText(self._translate("Main Buttons", "Select file"))
        self.btn_select.setStatusTip(
            self._translate("Main Buttons", "Select MIUI Zip file"))
        self.btn_url.setText(self._translate("Main Buttons", "Enter URL"))
        self.btn_url.setStatusTip(
            self._translate("Main Buttons", "Enter a URL of a Zip file"))
        self.btn_create.setText(self._translate("Main Buttons", "Create"))
        self.btn_create.setStatusTip(
            self._translate("Main Buttons", "Create the selected output zip"))
        self.menu_file.setTitle(self._translate("Menu bar", "File"))
        self.menu_language.setTitle(self._translate("Menu bar", "Language"))
        self.menu_help.setTitle(self._translate("Menu bar", "Help"))
        self.action_open_zip.setText(self._translate("Menu bar", "Open ZIP"))
        self.action_open_zip.setStatusTip(
            self._translate("Menu bar", "Select MIUI Zip file"))
        self.action_open_remote_zip.setText(
            self._translate("Menu bar", "Enter URL"))
        self.action_open_remote_zip.setStatusTip(
            self._translate("Menu bar", "Enter a URL of a Zip file"))
        self.action_quit.setText(self._translate("Menu bar", "Quit"))
        self.action_quit.setStatusTip(
            self._translate("Menu bar", "Exits the application"))
        self.action_language_sq.setText(self._translate(
            "Menu bar", "Albanian"))
        self.action_language_ar.setText(self._translate("Menu bar", "Arabic"))
        self.action_language_ca.setText(self._translate("Menu bar", "Catalan"))
        self.action_language_zh_CN.setText(
            self._translate("Menu bar", "Chinese Simplified"))
        self.action_language_hr.setText(self._translate(
            "Menu bar", "Croatian"))
        self.action_language_cs.setText(self._translate("Menu bar", "Czech"))
        self.action_language_nl.setText(self._translate("Menu bar", "Dutch"))
        self.action_language_en.setText(self._translate("Menu bar", "English"))
        self.action_language_fr.setText(self._translate("Menu bar", "French"))
        self.action_language_de.setText(self._translate("Menu bar", "German"))
        self.action_language_el.setText(self._translate("Menu bar", "Greek"))
        self.action_language_hi.setText(self._translate("Menu bar", "Hindi"))
        self.action_language_id.setText(
            self._translate("Menu bar", "Indonesian"))
        self.action_language_it.setText(self._translate("Menu bar", "Italian"))
        self.action_language_ms.setText(self._translate("Menu bar", "Malay"))
        self.action_language_fa.setText(self._translate("Menu bar", "Persian"))
        self.action_language_pl.setText(self._translate("Menu bar", "Polish"))
        self.action_language_pt_BR.setText(
            self._translate("Menu bar", "Portuguese, Brazilian"))
        self.action_language_ro.setText(self._translate(
            "Menu bar", "Romanian"))
        self.action_language_ru.setText(self._translate("Menu bar", "Russian"))
        self.action_language_sl.setText(
            self._translate("Menu bar", "Slovenian"))
        self.action_language_es_ES.setText(
            self._translate("Menu bar", "Spanish"))
        self.action_language_tr.setText(self._translate("Menu bar", "Turkish"))
        self.action_language_uk.setText(
            self._translate("Menu bar", "Ukrainian"))
        self.action_language_vi.setText(
            self._translate("Menu bar", "Vietnamese"))
        self.action_report_bug.setText(
            self._translate("Menu bar", "Report Bug"))
        self.action_report_bug.setStatusTip(
            self._translate("Menu bar", "Submit an issue "
                            "in case anything is wrong"))
        self.action_donate.setText(self._translate("Menu bar", "Donate"))
        self.action_donate.setStatusTip(
            self._translate("Menu bar", "Show us some love"))
        self.action_about.setText(self._translate("Menu bar", "About"))
        self.action_about.setStatusTip(
            self._translate("Menu bar", "About this tool"))
        self.action_website.setText(self._translate("Menu bar", "Website"))
        self.action_website.setStatusTip(
            self._translate("Menu bar", "Visit tool website"))
        self.statusBar().showMessage(self._translate("Status Box", "Ready"))

    def center(self):
        """
        Dynamically center the window in screen
        """
        # https://gist.github.com/saleph/163d73e0933044d0e2c4
        # geometry of the main window
        window = self.frameGeometry()
        # center point of screen
        center_point = QDesktopWidget().availableGeometry().center()
        # move rectangle's center point to screen's center point
        window.moveCenter(center_point)
        # top left of rectangle becomes top left of window centering it
        self.move(window.topLeft())

    def change_language(self, lang: str):
        """
        Update strings language and settings
        """
        update_settings(dict({'language': lang}))
        adjust_layout_direction(self, lang)
        self._translateanslator.load(f'{current_dir}/i18n/{lang}.qm')
        self.re_translate_ui()
        logging.info(f'Language is switched to {lang}')

    def select_file(self):
        """
        Opens select file Dialog
        """
        dialog = QFileDialog()
        filepath = dialog.getOpenFileName(
            self, self._translate('Select Files Dialog',
                                  'Select MIUI zip'), '',
            self._translate('Select Files Dialog', 'MIUI zip files') +
            ' (*.zip)')[0]
        if not filepath:
            self.statusBar().showMessage(
                self._translate("Status Box", "Please select a file!"))
            self.status_box.setText(
                self._translate("Status Box", "Please select a file!"))
            return
        self.filepath = Path(filepath).absolute()
        self.filename = self.filepath.name
        self.status_box.setText(
            self._translate("Status Box", f"File {self.filename} is selected"))
        self.statusBar().showMessage(
            self._translate("Status Box", f"File {self.filename} is selected"))
        logging.info(f'File {self.filename} is selected')

    def enter_url(self):
        """
        Enter URL Dialog
        """
        dialog = InputDialog(self._translate('Enter URL Dialog',
                                             'Remote Zip URL'),
                             self._translate('Enter URL Dialog',
                                             'Enter a MIUI zip direct link:'),
                             self._translate('Enter URL Dialog', 'Set URL'),
                             self._translate('Enter URL Dialog', 'Cancel'),
                             parent=self.window_body)
        if dialog.exec_() == QDialog.Accepted:
            url = dialog.textValue()
            if "http" not in url or "ota.d.miui.com" not in url:
                message_box = MessageBox(
                    self._translate('Popup Message', 'Error'),
                    self._translate('Popup Message', 'Not a valid URL.'),
                    self._translate('Popup Message', 'OK'),
                    box_type="Warning",
                    parent=self.window_body)
                message_box.exec_()
                # if button_clicked == QMessageBox.Ok:
                #     pass
                return
            self.filepath = url
            self.filename = url.split("/")[-1]
            self.status_box.setText(
                self._translate("Status Box",
                                f"Remote file {self.filename} is selected."))
            logging.info(f'Remote file {self.filename} is selected')

    def create_zip(self):
        """
        creates output zip file
        """
        checked_radiobutton = None
        process = None
        if not self.filepath:
            error_box = MessageBox(self._translate('Popup Message', 'Error'),
                                   self._translate(
                                       'Popup Message',
                                       'You must select a ROM zip first!'),
                                   self._translate('Popup Message', 'OK'),
                                   box_type="Critical",
                                   parent=self.window_body)
            error_box.exec_()
            logging.info(f'No Zip error shown')
            return

        for button in self.process_type.findChildren(QRadioButton):
            if button.isChecked():
                checked_radiobutton = button.text()
                logging.info(f'Selected process ({button.text()})')
        if checked_radiobutton == 'Firmware':
            process = 'firmware'
        if checked_radiobutton == 'Non-ARB Firmware':
            process = 'nonarb'
        if checked_radiobutton == 'Firmware + Vendor':
            process = 'vendor'
        if checked_radiobutton == 'Firmware-less ROM':
            process = 'firmwareless'
        self.status_box.setText(
            self._translate("Status Box", f"Starting {process} job"))
        out_dir = Path(".").absolute() if isinstance(
            self.filepath, str) else self.filepath.parent
        firmware_creator = FlashableFirmwareCreator(str(self.filepath),
                                                    process, out_dir)
        self.progress_bar.setValue(1)
        logging.info(f'Starting extract job')
        self.progress_bar.setValue(5)
        self.status_box.setText(
            self._translate("Status Box", f"Unzipping MIUI ROM..."))
        self.progress_bar.setValue(20)
        logging.info(f'Unzipping {self.filename}')
        extracted = False
        try:
            firmware_creator.extract()
            extracted = True
        except RuntimeError as err:
            if str(err) == "Nothing found to extract!":
                message_box = MessageBox(
                    self._translate('Popup Message', 'Error'),
                    self._translate('Popup Message',
                                    'Unsupported operation for MTK!'),
                    self._translate('Popup Message', 'OK'),
                    box_type="Warning",
                    parent=self.window_body)
                message_box.exec_()
                self.status_box.setText(
                    self._translate("Status Box",
                                    "Error: Unsupported operation for MTK!"))
                logging.warning(f'Unsupported operation for MTK')
                firmware_creator.close()
                self.progress_bar.setValue(100)
            else:
                raise err
        if extracted:
            self.progress_bar.setValue(45)
            self.status_box.setText(
                self._translate("Status Box", "Generating updater-script..."))
            self.progress_bar.setValue(55)
            logging.info(f'Creating updater-script')
            firmware_creator.generate_updater_script()
            self.status_box.setText(
                self._translate("Status Box", "Creating zip.."))
            self.progress_bar.setValue(75)
            logging.info(f'Creating output zip')
            new_zip = firmware_creator.make_zip()
            firmware_creator.cleanup()
            firmware_creator.close()
            self.progress_bar.setValue(100)
            message_box = OutputMessageBox(
                self._translate('Popup Message', 'Done'),
                self._translate('Popup Message',
                                f'All Done! Output zip is {new_zip}'),
                self._translate('Popup Message', 'OK'),
                self._translate('Popup Message', 'Show in folder'),
                self.filepath,
                parent=self.window_body)
            clicked = message_box.exec_()
            if clicked:
                browse_file_directory(self.filepath)
            logging.info(f'Done')
            self.status_box.setText(self._translate("Status Box", "Ready"))
            self.statusBar().showMessage(self._translate(
                "Status Box", "Ready"))

    @staticmethod
    def open_link(link):
        """
        Opens link in browser
        """
        QDesktopServices.openUrl(QUrl(link))
        logging.info(f'{link} opened')

    def open_about(self):
        """
        Opens About box
        """
        about_box = AboutBox(self.lang)
        about_box.setup_ui()
        about_box.exec_()