class Main(plugin.Plugin): " dock Class " def initialize(self): " Init Class dock " self.dock = QDockWidget() self.dock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.boton = QPushButton(QIcon.fromTheme("media-eject"), ' Open Media ', self.dock) try: self.factory = KPluginLoader("dragonpart").factory() self.part = self.factory.create(self) self.boton.clicked.connect(lambda: self.part.openUrl(KUrl(str( QFileDialog.getOpenFileName(self.dock, ' Open Media File ', path.expanduser("~"), ';;'.join(['(*.{})'.format(e) for e in ['ogv', 'webm', 'avi', 'mpg', 'mpeg', '3gp', 'wmv', 'mp3', 'asf', 'dat', 'flv', 'flac', 'ogg', 'mkv', 'mov', 'swf', 'wav', 'rm', 'm4v', 'aaf', 'mp4', 'raw', '*']])))))) self.dock.setWidget(self.part.widget()) except: self.dock.setWidget(QLabel(""" <center> <h3>ಠ_ಠ<br> ERROR: Please, install Dragon Player and PyKDE ! </h3><br> <br><i> (Sorry, cant embed non-Qt Apps). </i>><center>""")) self.misc = self.locator.get_service('misc') self.misc.add_widget(self.dock, QIcon.fromTheme("applications-multimedia"), __doc__)
class QutePyEditor(QMainWindow): ''' Arranges an instance of the Qutepart editor and minimap in a widget ''' def __init__(self, parent=None): ''' Constructor. Just setting up member-variables. initQutePyEditor needs to be called to create sub-widgets. ''' super(QutePyEditor, self).__init__(parent) self._qutePy = None self._qutePyDockWidget = None self._miniMapWidget = None self._miniMapDockWidget = None def initQutePyEditor(self): self.setWindowTitle(self.__class__.__name__) self._qutePyDockWidget = QDockWidget(self) self._miniMapDockWidget = QDockWidget(self) self._qutePy = QutePy(self._qutePyDockWidget) self._miniMapWidget = MiniMapWidget(self._qutePy, parent=self._miniMapDockWidget) self._qutePyDockWidget.setWidget(self._qutePy) self._miniMapDockWidget.setWidget(self._miniMapWidget) self._miniMapDockWidget.setWindowTitle( self._miniMapWidget.__class__.__name__) self.addDockWidget(Qt.LeftDockWidgetArea, self._qutePyDockWidget) self.addDockWidget(Qt.RightDockWidgetArea, self._miniMapDockWidget)
class Main(plugin.Plugin): " dock Class " def initialize(self): " Init Class dock " self.dock = QDockWidget() self.dock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.boton = QPushButton(QIcon.fromTheme("document-open-recent"), 'Edit Track', self.dock) self.boton.setToolTip('Edit iCal: {}'.format(TRACK_FILE)) try: self.factory = KPluginLoader("ktimetrackerpart").factory() self.part = self.factory.create(self) self.part.setReadWrite(True) self.part.closeUrl() self.part.openUrl(KUrl(str(TRACK_FILE))) self.boton.clicked.connect(lambda: call('xdg-open {}'.format(TRACK_FILE), shell=True)) self.dock.setWidget(self.part.widget()) except: self.dock.setWidget(QLabel(""" <center> <h3>ಠ_ಠ<br> ERROR: Please, install kTimeTracker and PyKDE ! </h3><br> <br><i> (Sorry, cant embed non-Qt Apps). </i><center>""")) self.misc = self.locator.get_service('misc') self.misc.add_widget(self.dock, QIcon.fromTheme("user-away"), __doc__)
class Main(plugin.Plugin): " dock Class " def initialize(self): " Init Class dock " self.dock = QDockWidget() self.dock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.open = QAction(QIcon.fromTheme("document-open"), 'Open DIFF', self) self.diff = QAction(QIcon.fromTheme("document-new"), 'Make DIFF', self) self.diff.triggered.connect(self.run_gui_and_get_results) self.save = QAction(QIcon.fromTheme("document-save"), 'Save DIFF', self) self.save.triggered.connect(self.save_a_diff) self.patc = QAction(QIcon.fromTheme("document-edit"), 'PATCH it!', self) self.patc.triggered.connect(lambda: QMessageBox.information(self.dock, __doc__, ' Sorry. This Feature is not ready yet !, thank you... ')) QToolBar(self.dock).addActions((self.open, self.diff, self.save, self.patc)) try: self.factory = KPluginLoader("komparepart").factory() self.part = self.factory.create(self) self.dock.setWidget(self.part.widget()) self.open.triggered.connect(lambda: self.part.openUrl(KUrl(str( QFileDialog.getOpenFileName(self.dock, ' Open a DIFF file ', path.expanduser("~"), ';;(*.diff)'))))) except: self.dock.setWidget(QLabel(""" <center> <h3>ಠ_ಠ<br> ERROR: Please, install Kompare and PyKDE ! </h3><br> <br><i> (Sorry, cant embed non-Qt Apps). </i><center>""")) self.misc = self.locator.get_service('misc') self.misc.add_widget(self.dock, QIcon.fromTheme("edit-select-all"), __doc__) def run_gui_and_get_results(self): ' run_gui_and_get_results ' gui = Diff_GUI() if gui.diff_path is not None and path.isfile(gui.diff_path) is True: self.part.openUrl(KUrl(str(gui.diff_path))) return gui.diff_path def save_a_diff(self): ' save a diff ' out_file = path.abspath(str(QFileDialog.getSaveFileName(self.dock, 'Save a Diff file', path.expanduser("~"), ';;(*.diff)'))) inp_file = file(str(QUrl( self.part.url()).toString()).replace('file://', ''), 'r').read() end_file = file(out_file, 'w') end_file.write(inp_file) end_file.close()
class Main(plugin.Plugin): " dock Class " def initialize(self): " Init Class dock " self.dock = QDockWidget() self.dock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.boton = QAction(QIcon.fromTheme("list-add"), 'Open', self) self.saver = QAction(QIcon.fromTheme("document-save"), 'Save', self) self.apiss = QAction(QIcon.fromTheme("help"), 'Python API Help', self) QToolBar(self.dock).addActions((self.boton, self.saver, self.apiss)) try: self.factory = KPluginLoader("kigpart").factory() self.part = self.factory.create(self) self.part.setReadWrite(True) self.boton.triggered.connect(lambda: self.part.openUrl( KUrl( str( QFileDialog.getOpenFileName( self.dock, ' Open Geometry Plot ', path.expanduser("~"), ';;'.join([ '(*.{})'.format(e) for e in ['fig', 'kig', 'kigz', 'seg', 'fgeo'] ])))))) self.saver.triggered.connect(lambda: self.part.saveAs( KUrl( str( QFileDialog.getSaveFileName( self.dock, ' Save Geometry Plot ', path.expanduser("~"), ';;'.join([ '(*.{})'.format(e) for e in ['kig', 'kigz', 'fig'] ])))))) self.apiss.triggered.connect(lambda: open_new_tab( 'http://edu.kde.org/kig/manual/scripting-api/classObject.html') ) self.dock.setWidget(self.part.widget()) except: self.dock.setWidget( QLabel(""" <center> <h3>ಠ_ಠ<br> ERROR: Please, install KIG and PyKDE ! </h3><br> <br><i> (Sorry, cant embed non-Qt Apps). </i><center>""")) self.misc = self.locator.get_service('misc') self.misc.add_widget(self.dock, QIcon.fromTheme("accessories-calculator"), __doc__)
class Terminal(plugin.Plugin): " Terminal Class " def initialize(self): " Init Class Terminal " self.terminal = QDockWidget() self.terminal.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.terminal.setWindowTitle(__doc__) self.terminal.setStyleSheet('QDockWidget::title{text-align: center;}') try: self.factory = KPluginLoader("libkonsolepart").factory() self.terminal.setWidget(self.factory.create(self).widget()) except: self.terminal.setWidget(QLabel(""" <center> <h3>ಠ_ಠ<br> ERROR: Please, install Konsole Terminal and PyKDE ! </h3><br> <br><i> (Sorry, cant embed non-Qt Terminal Apps). </i><center>""")) self.misc = self.locator.get_service('misc') self.misc.add_widget(self.terminal, QIcon.fromTheme("utilities-terminal"), __doc__)
class Main(plugin.Plugin): " dock Class " def initialize(self): " Init Class dock " self.dock = QDockWidget() self.dock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.boton = QAction(QIcon.fromTheme("list-add"), 'Open', self) self.saver = QAction(QIcon.fromTheme("document-save"), 'Save', self) self.apiss = QAction(QIcon.fromTheme("help"), 'Python API Help', self) QToolBar(self.dock).addActions((self.boton, self.saver, self.apiss)) try: self.factory = KPluginLoader("kigpart").factory() self.part = self.factory.create(self) self.part.setReadWrite(True) self.boton.triggered.connect(lambda: self.part.openUrl(KUrl(str( QFileDialog.getOpenFileName(self.dock, ' Open Geometry Plot ', path.expanduser("~"), ';;'.join(['(*.{})'.format(e) for e in ['fig', 'kig', 'kigz', 'seg', 'fgeo']])))))) self.saver.triggered.connect(lambda: self.part.saveAs(KUrl(str( QFileDialog.getSaveFileName(self.dock, ' Save Geometry Plot ', path.expanduser("~"), ';;'.join(['(*.{})'.format(e) for e in ['kig', 'kigz', 'fig']]) ))))) self.apiss.triggered.connect(lambda: open_new_tab( 'http://edu.kde.org/kig/manual/scripting-api/classObject.html')) self.dock.setWidget(self.part.widget()) except: self.dock.setWidget(QLabel(""" <center> <h3>ಠ_ಠ<br> ERROR: Please, install KIG and PyKDE ! </h3><br> <br><i> (Sorry, cant embed non-Qt Apps). </i><center>""")) self.misc = self.locator.get_service('misc') self.misc.add_widget(self.dock, QIcon.fromTheme("accessories-calculator"), __doc__)
class Main(plugin.Plugin): " dock Class " def initialize(self): " Init Class dock " self.dock = QDockWidget() self.dock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet("QDockWidget::title{text-align: center;}") self.scrollable = QScrollArea() self.dock.setWidget(self.scrollable) try: self.factory = KPluginLoader("klinkstatuspart").factory() self.scrollable.setWidget(self.factory.create(self).widget()) except: self.scrollable.setWidget( QLabel( """ <center> <h3>ಠ_ಠ<br> ERROR: Please, install KLinkCheck and PyKDE ! </h3><br> <br><i> (Sorry, cant embed non-Qt Apps). </i><center>""" ) ) self.misc = self.locator.get_service("misc") self.misc.add_widget(self.dock, QIcon.fromTheme("insert-link"), __doc__)
def __init__(self, params_pipe, number_pipe, data_pipe, mads_pipe, peaks_pipe, probe_path=None, screen_resolution=None): QMainWindow.__init__(self) # Receive parameters. params = params_pipe[0].recv() self.probe = load_probe(probe_path) self._nb_samples = params['nb_samples'] self._sampling_rate = params['sampling_rate'] self._display_list = list(range(self.probe.nb_channels)) self._params = { 'nb_samples': self._nb_samples, 'sampling_rate': self._sampling_rate, 'time': { 'min': 10.0, # ms 'max': 1000.0, # ms 'init': 100.0, # ms }, 'voltage': { 'min': 10.0, # µV 'max': 10e+3, # µV 'init': 20.0, # µV }, 'mads': { 'min': 0.0, # µV 'max': 100, # µV 'init': 3, # µV }, 'channels': self._display_list } self._canvas = TraceCanvas(probe_path=probe_path, params=self._params) central_widget = self._canvas.native # Create controls widgets. label_time = QLabel() label_time.setText(u"time") label_time_unit = QLabel() label_time_unit.setText(u"ms") self._dsp_time = QDoubleSpinBox() self._dsp_time.setMinimum(self._params['time']['min']) self._dsp_time.setMaximum(self._params['time']['max']) self._dsp_time.setValue(self._params['time']['init']) self._dsp_time.valueChanged.connect(self._on_time_changed) label_display_mads = QLabel() label_display_mads.setText(u"Display Mads") self._display_mads = QCheckBox() self._display_mads.stateChanged.connect(self._on_mads_display) label_display_peaks = QLabel() label_display_peaks.setText(u"Display Peaks") self._display_peaks = QCheckBox() self._display_peaks.stateChanged.connect(self._on_peaks_display) label_mads = QLabel() label_mads.setText(u"Mads") label_mads_unit = QLabel() label_mads_unit.setText(u"unit") self._dsp_mads = QDoubleSpinBox() self._dsp_mads.setMinimum(self._params['mads']['min']) self._dsp_mads.setMaximum(self._params['mads']['max']) self._dsp_mads.setValue(self._params['mads']['init']) self._dsp_mads.valueChanged.connect(self._on_mads_changed) label_voltage = QLabel() label_voltage.setText(u"voltage") label_voltage_unit = QLabel() label_voltage_unit.setText(u"µV") self._dsp_voltage = QDoubleSpinBox() self._dsp_voltage.setMinimum(self._params['voltage']['min']) self._dsp_voltage.setMaximum(self._params['voltage']['max']) self._dsp_voltage.setValue(self._params['voltage']['init']) self._dsp_voltage.valueChanged.connect(self._on_voltage_changed) # Color spikes self._color_spikes = QCheckBox() self._color_spikes.setText('See Spikes color') self._color_spikes.setCheckState(Qt.Checked) self._color_spikes.stateChanged.connect(self.display_spikes_color) # self._selection_channels.setGeometry(QtCore.QRect(10, 10, 211, 291)) spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) # Create controls grid. grid = QGridLayout() # # Add time row. grid.addWidget(label_time, 0, 0) grid.addWidget(self._dsp_time, 0, 1) grid.addWidget(label_time_unit, 0, 2) # # Add voltage row. grid.addWidget(label_voltage, 1, 0) grid.addWidget(self._dsp_voltage, 1, 1) grid.addWidget(label_voltage_unit, 1, 2) # # Add Mads widgets grid.addWidget(label_display_mads, 3, 0) grid.addWidget(self._display_mads, 3, 1) grid.addWidget(label_mads, 4, 0) grid.addWidget(self._dsp_mads, 4, 1) grid.addWidget(label_mads_unit, 4, 2) grid.addWidget(self._color_spikes, 5, 0) # # Add spacer. grid.addItem(spacer) # # Create info group. controls_group = QGroupBox() controls_group.setLayout(grid) self._selection_channels = QListWidget() self._selection_channels.setSelectionMode( QAbstractItemView.ExtendedSelection ) for i in range(self.probe.nb_channels): item = QListWidgetItem("Channel %i" % i) self._selection_channels.addItem(item) self._selection_channels.item(i).setSelected(True) def add_channel(): items = self._selection_channels.selectedItems() self._display_list = [] for i in range(len(items)): self._display_list.append(i) self._on_channels_changed() # self._selection_channels.itemClicked.connect(add_channel) nb_channel = self.probe.nb_channels self._selection_channels.itemSelectionChanged.connect(lambda: self.selected_channels(nb_channel)) # Create info grid. channels_grid = QGridLayout() # # Add Channel selection # grid.addWidget(label_selection, 3, 0) channels_grid.addWidget(self._selection_channels, 0, 1) # # Add spacer. channels_grid.addItem(spacer) # Create controls group. channels_group = QGroupBox() channels_group.setLayout(channels_grid) # # Create controls dock. channels_dock = QDockWidget() channels_dock.setWidget(channels_group) channels_dock.setWindowTitle("Channels selection") # # Create controls dock. control_dock = QDockWidget() control_dock.setWidget(controls_group) control_dock.setWindowTitle("Controls") # Create info widgets. label_time = QLabel() label_time.setText(u"time") self._label_time_value = QLineEdit() self._label_time_value.setText(u"0") self._label_time_value.setReadOnly(True) self._label_time_value.setAlignment(Qt.AlignRight) label_time_unit = QLabel() label_time_unit.setText(u"s") info_buffer_label = QLabel() info_buffer_label.setText(u"buffer") self._info_buffer_value_label = QLineEdit() self._info_buffer_value_label.setText(u"0") self._info_buffer_value_label.setReadOnly(True) self._info_buffer_value_label.setAlignment(Qt.AlignRight) info_buffer_unit_label = QLabel() info_buffer_unit_label.setText(u"") info_probe_label = QLabel() info_probe_label.setText(u"probe") info_probe_value_label = QLineEdit() info_probe_value_label.setText(u"{}".format(probe_path)) info_probe_value_label.setReadOnly(True) # TODO place the following info in another grid? info_probe_unit_label = QLabel() info_probe_unit_label.setText(u"") info_spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) # Create info grid. info_grid = QGridLayout() # # Time row. info_grid.addWidget(label_time, 0, 0) info_grid.addWidget(self._label_time_value, 0, 1) info_grid.addWidget(label_time_unit, 0, 2) # # Buffer row. info_grid.addWidget(info_buffer_label, 1, 0) info_grid.addWidget(self._info_buffer_value_label, 1, 1) info_grid.addWidget(info_buffer_unit_label, 1, 2) # # Probe row. info_grid.addWidget(info_probe_label, 2, 0) info_grid.addWidget(info_probe_value_label, 2, 1) info_grid.addWidget(info_probe_unit_label, 2, 2) # # Spacer. info_grid.addItem(info_spacer) # Create info group. info_group = QGroupBox() info_group.setLayout(info_grid) # Create info dock. info_dock = QDockWidget() info_dock.setWidget(info_group) info_dock.setWindowTitle("Info") # Create thread. thread = Thread(number_pipe, data_pipe, mads_pipe, peaks_pipe) thread.number_signal.connect(self._number_callback) thread.reception_signal.connect(self._reception_callback) thread.start() # Add dockable windows. self.addDockWidget(Qt.LeftDockWidgetArea, control_dock) self.addDockWidget(Qt.LeftDockWidgetArea, info_dock) self.addDockWidget(Qt.LeftDockWidgetArea, channels_dock) # Set central widget. self.setCentralWidget(central_widget) # Set window size. if screen_resolution is not None: screen_width = screen_resolution.width() screen_height = screen_resolution.height() self.resize(screen_width, screen_height) # Set window title. self.setWindowTitle("SpyKING Circus ORT - Read 'n' Qt display") print(" ") # TODO remove?
def __init__(self, params_pipe, number_pipe, templates_pipe, spikes_pipe, probe_path=None, screen_resolution=None): QMainWindow.__init__(self) # Receive parameters. params = params_pipe[0].recv() self.probe = load_probe(probe_path) self._nb_samples = params['nb_samples'] self._sampling_rate = params['sampling_rate'] self._display_list = [] self._params = { 'nb_samples': self._nb_samples, 'sampling_rate': self._sampling_rate, 'time': { 'min': 10.0, # ms 'max': 100.0, # ms 'init': 100.0, # ms }, 'voltage': { 'min': -200, # µV 'max': 20e+1, # µV 'init': 50.0, # µV }, 'templates': self._display_list } self._canvas_mea = MEACanvas(probe_path=probe_path, params=self._params) self._canvas_template = TemplateCanvas(probe_path=probe_path, params=self._params) self._canvas_rate = RateCanvas(probe_path=probe_path, params=self._params) self._canvas_isi = ISICanvas(probe_path=probe_path, params=self._params) self.cells = Cells({}) self._nb_buffer = 0 # TODO ISI self.isi_bin_width, self.isi_x_max = 2, 25.0 canvas_template_widget = self._canvas_template.native canvas_mea = self._canvas_mea.native canvas_rate = self._canvas_rate.native canvas_isi = self._canvas_isi.native # Create controls widgets. label_time = QLabel() label_time.setText(u"time") label_time_unit = QLabel() label_time_unit.setText(u"ms") self._dsp_time = QDoubleSpinBox() self._dsp_time.setMinimum(self._params['time']['min']) self._dsp_time.setMaximum(self._params['time']['max']) self._dsp_time.setValue(self._params['time']['init']) self._dsp_time.valueChanged.connect(self._on_time_changed) label_voltage = QLabel() label_voltage.setText(u"voltage") label_voltage_unit = QLabel() label_voltage_unit.setText(u"µV") self._dsp_voltage = QDoubleSpinBox() self._dsp_voltage.setMinimum(self._params['voltage']['min']) self._dsp_voltage.setMaximum(self._params['voltage']['max']) self._dsp_voltage.setValue(self._params['voltage']['init']) self._dsp_voltage.valueChanged.connect(self._on_voltage_changed) label_binsize = QLabel() label_binsize.setText(u"Bin size") label_binsize_unit = QLabel() label_binsize_unit.setText(u"second") self._dsp_binsize = QDoubleSpinBox() self._dsp_binsize.setRange(0.1, 10) self._dsp_binsize.setSingleStep(0.1) self.bin_size = 1 self._dsp_binsize.setValue(self.bin_size) self._dsp_binsize.valueChanged.connect(self._on_binsize_changed) label_zoomrates = QLabel() label_zoomrates.setText(u'Zoom rates') self._zoom_rates = QDoubleSpinBox() self._zoom_rates.setRange(1, 50) self._zoom_rates.setSingleStep(0.1) self._zoom_rates.setValue(1) self._zoom_rates.valueChanged.connect(self._on_zoomrates_changed) label_time_window = QLabel() label_time_window.setText(u'Time window rates') label_time_window_unit = QLabel() label_time_window_unit.setText(u'second') self._dsp_tw_rate = QDoubleSpinBox() self._dsp_tw_rate.setRange(1, 50) self._dsp_tw_rate.setSingleStep(self.bin_size) self._dsp_tw_rate.setValue(50 * self.bin_size) self._dsp_tw_rate.valueChanged.connect(self._on_time_window_changed) label_tw_from_start = QLabel() label_tw_from_start.setText('Time scale from start') self._tw_from_start = QCheckBox() self._tw_from_start.setChecked(True) self._selection_templates = QTableWidget() self._selection_templates.setSelectionMode( QAbstractItemView.ExtendedSelection ) self._selection_templates.setColumnCount(3) self._selection_templates.setVerticalHeaderLabels(['Nb template', 'Channel', 'Amplitude']) self._selection_templates.insertRow(0) self._selection_templates.setItem(0, 0, QTableWidgetItem('Nb template')) self._selection_templates.setItem(0, 1, QTableWidgetItem('Channel')) self._selection_templates.setItem(0, 2, QTableWidgetItem('Amplitude')) # self._selection_channels.setGeometry(QtCore.QRect(10, 10, 211, 291)) # for i in range(self.nb_templates): # numRows = self.tableWidget.rowCount() # self.tableWidget.insertRow(numRows) # item = QTableWidgetItem("Template %i" % i) # self._selection_templates.addItem(item) # self._selection_templates.item(i).setSelected(False) spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) # Create controls grid. grid = QGridLayout() # # Add time row. grid.addWidget(label_time, 0, 0) grid.addWidget(self._dsp_time, 0, 1) grid.addWidget(label_time_unit, 0, 2) # # Add voltage row. grid.addWidget(label_voltage, 1, 0) grid.addWidget(self._dsp_voltage, 1, 1) grid.addWidget(label_voltage_unit, 1, 2) # # Add binsize row. grid.addWidget(label_binsize, 2, 0) grid.addWidget(self._dsp_binsize, 2, 1) grid.addWidget(label_binsize_unit, 2, 2) # # Add zoom rate grid.addWidget(label_zoomrates, 3, 0) grid.addWidget(self._zoom_rates, 3, 1) # Add a double checkbox for time window grid.addWidget(label_time_window, 4, 0) grid.addWidget(self._dsp_tw_rate, 4, 1) grid.addWidget(label_time_window_unit, 4, 2) ## Add checkbox to display the rates from start grid.addWidget(label_tw_from_start, 5, 0) grid.addWidget(self._tw_from_start, 5, 1) # # Add spacer. grid.addItem(spacer) # # Create info group. controls_group = QGroupBox() controls_group.setLayout(grid) # Create info grid. templates_grid = QGridLayout() # # Add Channel selection # grid.addWidget(label_selection, 3, 0) templates_grid.addWidget(self._selection_templates, 0, 1) def add_template(): items = self._selection_templates.selectedItems() self._display_list = [] for i in range(len(items)): self._display_list.append(i) self._on_templates_changed() # self._selection_templates.itemClicked.connect(add_template) # Template selection signals self._selection_templates.itemSelectionChanged.connect(lambda: self.selected_templates( self.nb_templates)) # Checkbox to display all the rates self._tw_from_start.stateChanged.connect(self.time_window_rate_full) # self._selection_templates.itemPressed(0, 1).connect(self.sort_template()) # # Add spacer. templates_grid.addItem(spacer) # Create controls group. templates_group = QGroupBox() templates_group.setLayout(templates_grid) # # Create controls dock. templates_dock = QDockWidget() templates_dock.setWidget(templates_group) templates_dock.setWindowTitle("Channels selection") # # Create controls dock. control_dock = QDockWidget() control_dock.setWidget(controls_group) control_dock.setWindowTitle("Controls") # Create info widgets. label_time = QLabel() label_time.setText(u"time") self._label_time_value = QLineEdit() self._label_time_value.setText(u"0") self._label_time_value.setReadOnly(True) self._label_time_value.setAlignment(Qt.AlignRight) label_time_unit = QLabel() label_time_unit.setText(u"s") info_buffer_label = QLabel() info_buffer_label.setText(u"buffer") self._info_buffer_value_label = QLineEdit() self._info_buffer_value_label.setText(u"0") self._info_buffer_value_label.setReadOnly(True) self._info_buffer_value_label.setAlignment(Qt.AlignRight) info_buffer_unit_label = QLabel() info_buffer_unit_label.setText(u"") info_probe_label = QLabel() info_probe_label.setText(u"probe") info_probe_value_label = QLineEdit() info_probe_value_label.setText(u"{}".format(probe_path)) info_probe_value_label.setReadOnly(True) # TODO place the following info in another grid? info_probe_unit_label = QLabel() info_probe_unit_label.setText(u"") info_spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) # Create info grid. info_grid = QGridLayout() # # Time row. info_grid.addWidget(label_time, 0, 0) info_grid.addWidget(self._label_time_value, 0, 1) info_grid.addWidget(label_time_unit, 0, 2) # # Buffer row. info_grid.addWidget(info_buffer_label, 1, 0) info_grid.addWidget(self._info_buffer_value_label, 1, 1) info_grid.addWidget(info_buffer_unit_label, 1, 2) # # Probe row. info_grid.addWidget(info_probe_label, 2, 0) info_grid.addWidget(info_probe_value_label, 2, 1) info_grid.addWidget(info_probe_unit_label, 2, 2) # # Spacer. info_grid.addItem(info_spacer) # Create info group. info_group = QGroupBox() info_group.setLayout(info_grid) # Create info dock. info_dock = QDockWidget() info_dock.setWidget(info_group) info_dock.setWindowTitle("Info") # Create thread. thread = Thread(number_pipe, templates_pipe, spikes_pipe) thread.number_signal.connect(self._number_callback) thread.reception_signal.connect(self._reception_callback) thread.start() # Add dockable windows. self.addDockWidget(Qt.LeftDockWidgetArea, control_dock) self.addDockWidget(Qt.LeftDockWidgetArea, info_dock) self.addDockWidget(Qt.LeftDockWidgetArea, templates_dock) # Add Grid Layout for canvas canvas_grid = QGridLayout() group_canv_temp = QDockWidget() group_canv_temp.setWidget(canvas_template_widget) group_canv_mea = QDockWidget() group_canv_mea.setWidget(canvas_mea) group_canv_rate = QDockWidget() group_canv_rate.setWidget(canvas_rate) group_canv_isi = QDockWidget() group_canv_isi.setWidget(canvas_isi) canvas_grid.addWidget(group_canv_temp, 0, 0) canvas_grid.addWidget(group_canv_mea, 0, 1) canvas_grid.addWidget(group_canv_rate, 1, 1) canvas_grid.addWidget(group_canv_isi, 1, 0) canvas_group = QGroupBox() canvas_group.setLayout(canvas_grid) # Set central widget. self.setCentralWidget(canvas_group) # Set window size. if screen_resolution is not None: screen_width = screen_resolution.width() screen_height = screen_resolution.height() self.resize(screen_width, screen_height) # Set window title. self.setWindowTitle("SpyKING Circus ORT - Read 'n' Qt display") print(" ") # TODO remove?
class MyMainWindow(QMainWindow): ' Main Window ' def __init__(self, parent=None): ' Initialize QWidget inside MyMainWindow ' super(MyMainWindow, self).__init__(parent) self.statusBar().showMessage(__doc__.title()) self.setWindowTitle(__doc__) self.setMinimumSize(600, 800) self.setMaximumSize(2048, 1024) self.resize(1024, 800) self.setWindowIcon(QIcon.fromTheme("face-monkey")) if not A11Y: self.setStyleSheet('''QWidget{color:#fff;font-family:Oxygen} QWidget:item:hover, QWidget:item:selected { background-color: cyan; color: #000 } QWidget:disabled { color: #404040; background-color: #323232 } QWidget:focus { border: 1px solid cyan } QPushButton { background-color: gray; padding: 3px; border: 1px solid gray; border-radius: 9px; margin: 0;font-size: 12px; padding-left: 5px; padding-right: 5px } QLineEdit, QTextEdit { background-color: #4a4a4a; border: 1px solid gray; border-radius: 0; font-size: 12px; } QPushButton:pressed { background-color: #323232 } QComboBox { background-color: #4a4a4a; padding-left: 9px; border: 1px solid gray; border-radius: 5px; } QComboBox:pressed { background-color: gray } QComboBox QAbstractItemView, QMenu { border: 1px solid #4a4a4a; background:grey; selection-background-color: cyan; selection-color: #000; } QSlider { padding: 3px; font-size: 8px; padding-left: 2px; padding-right: 2px; border: 5px solid #1e1e1e } QSlider::sub-page:vertical { background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1, y2:0.27, stop:0 rgba(255, 0, 0, 255), stop:1 rgba(50, 0, 0, 200)); border: 4px solid #1e1e1e; border-radius: 5px } QSlider::add-page:vertical { background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1, y2:0.27, stop:0 rgba(0, 255, 0, 255), stop:1 rgba(0, 99, 0, 255)); border: 4px solid #1e1e1e; border-radius: 5px; } QSlider::handle:vertical { background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1, y2:0.273, stop:0 rgba(0, 0, 0, 255), stop:1 gray); height: 5px; border: 1px dotted #fff; text-align: center; border-top-left-radius: 2px; border-bottom-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius 2px; margin-left: 2px; margin-right: 2px; } QSlider::handle:vertical:hover { border: 1px solid cyan } QSlider::sub-page:vertical:disabled { background: #bbb; border-color: #999; } QSlider::add-page:vertical:disabled { background: #eee; border-color: #999; } QSlider::handle:vertical:disabled { background: #eee; border: 1px solid #aaa; border-radius: 4px; } QToolBar, QStatusBar, QDockWidget::title{background-color:#323232;} QToolBar::handle, QToolBar::handle:vertical, QToolBar::handle:horizontal { border: 1px solid gray; border-radius: 9px; width: 19px; height: 19px; margin: 0.5px } QGroupBox { border: 1px solid gray; border-radius: 9px; padding-top: 9px; } QStatusBar, QToolBar::separator:horizontal, QToolBar::separator:vertical {color:gray} QScrollBar:vertical{ background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #212121,stop: 1.0 #323232); width: 10px; } QScrollBar:horizontal{ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #212121,stop: 1.0 #323232); height: 10px; } QScrollBar::handle:vertical{ padding: 2px; min-height: 50px; background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #585858,stop: 1.0 #404040); border-radius: 5px; border: 1px solid #191919; } QScrollBar::handle:horizontal{ padding: 2px; min-width: 50px; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #585858,stop: 1.0 #404040); border-radius: 5px; border: 1px solid #191919; } QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical, QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { background: none; border: none; } QDockWidget::close-button, QDockWidget::float-button { border: 1px solid gray; border-radius: 3px; background: darkgray; }''') self.process = QProcess() self.process.readyReadStandardOutput.connect(self.read_output) self.process.readyReadStandardError.connect(self.read_errors) self.process.finished.connect(self._process_finished) self.process.error.connect(self._process_finished) self.group0, self.group1 = QGroupBox("Options"), QGroupBox("Paths") self.group2 = QGroupBox("Nodes") self.group3 = QGroupBox("Python Code") self.group4, self.group5 = QGroupBox("Logs"), QGroupBox("Backend") g0grid, g1vlay = QGridLayout(self.group0), QVBoxLayout(self.group1) g5vlay = QVBoxLayout(self.group5) self.treeview_nodes, self.textedit_source = QTextEdit(), QTextEdit() self.dock1, self.dock2 = QDockWidget(), QDockWidget() self.output, self.dock3 = QTextEdit(), QDockWidget() self.treeview_nodes.setAutoFormatting(QTextEdit.AutoAll) self.treeview_nodes.setWordWrapMode(QTextOption.NoWrap) self.dock1.setWidget(self.treeview_nodes) self.dock2.setWidget(self.textedit_source) self.dock3.setWidget(self.output) self.dock1.setWindowTitle("Tree") self.dock2.setWindowTitle("Sources") self.dock3.setWindowTitle("STDOutput") featur = QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable self.dock1.setFeatures(featur) self.dock2.setFeatures(featur) self.dock3.setFeatures(featur) QVBoxLayout(self.group2).addWidget(self.dock1) QVBoxLayout(self.group3).addWidget(self.dock2) QVBoxLayout(self.group4).addWidget(self.dock3) self.slider1, self.slider2 = QSlider(), QSlider() g0grid.addWidget(self.slider1, 0, 0) g0grid.addWidget(QLabel('Use Debug'), 0, 1) self.slider2.setValue(1) g0grid.addWidget(self.slider2, 1, 0) g0grid.addWidget(QLabel('Use verbose'), 1, 1) self.slider3, self.slider4 = QSlider(), QSlider() self.slider3.setValue(1) g0grid.addWidget(self.slider3, 2, 0) g0grid.addWidget(QLabel('Show compiling progress'), 2, 1) self.slider4.setValue(1) g0grid.addWidget(self.slider4, 3, 0) g0grid.addWidget(QLabel('Show Scons building debug'), 3, 1) self.slider5, self.slider6 = QSlider(), QSlider() g0grid.addWidget(self.slider5, 4, 0) g0grid.addWidget(QLabel('Keep debug unstriped binary'), 4, 1) g0grid.addWidget(self.slider6, 5, 0) g0grid.addWidget(QLabel('Traced execution outputs'), 5, 1) self.slider7, self.slider8 = QSlider(), QSlider() self.slider7.setValue(1) g0grid.addWidget(self.slider7, 6, 0) g0grid.addWidget(QLabel('Remove the build folder'), 6, 1) g0grid.addWidget(self.slider8, 7, 0) g0grid.addWidget(QLabel('No Python Optimizations'), 7, 1) self.slider9, self.slider10 = QSlider(), QSlider() g0grid.addWidget(self.slider9, 8, 0) g0grid.addWidget(QLabel('No Statements line numbers'), 8, 1) g0grid.addWidget(self.slider10, 9, 0) g0grid.addWidget(QLabel('Execute the output binary'), 9, 1) self.slider11, self.slider12 = QSlider(), QSlider() g0grid.addWidget(self.slider11, 10, 0) g0grid.addWidget(QLabel('Warning detected implicit exceptions'), 10, 1) g0grid.addWidget(self.slider12, 11, 0) g0grid.addWidget(QLabel('Keep the PYTHONPATH, do not Reset it'), 11, 1) self.slider13 = QSlider() g0grid.addWidget(self.slider13, 12, 0) g0grid.addWidget(QLabel('Enhance compile, CPython incompatible'), 12, 1) self.slider1a, self.slider2a = QSlider(), QSlider() g0grid.addWidget(self.slider1a, 0, 2) g0grid.addWidget(QLabel('Descendent Recursive Compile'), 0, 3) self.slider2a.setValue(1) g0grid.addWidget(self.slider2a, 1, 2) g0grid.addWidget(QLabel('Force non recursive compile'), 1, 3) self.slider3a, self.slider4a = QSlider(), QSlider() g0grid.addWidget(self.slider3a, 2, 2) g0grid.addWidget(QLabel('STD Lib Recursive Compile'), 2, 3) g0grid.addWidget(self.slider4a, 3, 2) g0grid.addWidget(QLabel('Enforce the use of Clang'), 3, 3) self.slider5a, self.slider6a = QSlider(), QSlider() self.slider5a.setValue(1) g0grid.addWidget(self.slider5a, 4, 2) g0grid.addWidget(QLabel('Use G++ link time optimizations'), 4, 3) g0grid.addWidget(self.slider6a, 5, 2) g0grid.addWidget(QLabel('Disable the console window'), 5, 3) self.slider7a, self.slider8a = QSlider(), QSlider() g0grid.addWidget(self.slider7a, 6, 2) g0grid.addWidget(QLabel('Force compile for MS Windows'), 6, 3) g0grid.addWidget(self.slider8a, 7, 2) g0grid.addWidget(QLabel('Use Python Debug versions'), 7, 3) self.slider9a, self.slider10a = QSlider(), QSlider() self.slider9a.setValue(1) g0grid.addWidget(self.slider9a, 8, 2) g0grid.addWidget(QLabel('Create standalone executable'), 8, 3) g0grid.addWidget(self.slider10a, 9, 2) g0grid.addWidget(QLabel('Enable Standalone mode build'), 9, 3) self.slider11a, self.slider12a = QSlider(), QSlider() g0grid.addWidget(self.slider11a, 10, 2) g0grid.addWidget(QLabel('Make module executable instead of app'), 10, 3) g0grid.addWidget(self.slider12a, 11, 2) g0grid.addWidget(QLabel('No froze module of stdlib as bytecode'), 11, 3) self.slider13a = QSlider() g0grid.addWidget(self.slider13a, 12, 2) g0grid.addWidget(QLabel('Force use of MinGW on MS Windows'), 12, 3) for each_widget in (self.slider1, self.slider2, self.slider3, self.slider4, self.slider5, self.slider6, self.slider7, self.slider8, self.slider9, self.slider10, self.slider11, self.slider12, self.slider13, self.slider1a, self.slider2a, self.slider3a, self.slider4a, self.slider5a, self.slider6a, self.slider7a, self.slider8a, self.slider9a, self.slider10a, self.slider11a, self.slider12a, self.slider13a): each_widget.setRange(0, 1) each_widget.setCursor(QCursor(Qt.OpenHandCursor)) each_widget.setTickInterval(1) each_widget.TickPosition(QSlider.TicksBothSides) self.combo1 = QComboBox() self.combo1.addItems(('2.7', '2.6', '3.2', '3.3')) g5vlay.addWidget(QLabel('Python Version')) g5vlay.addWidget(self.combo1) self.combo2 = QComboBox() self.combo2.addItems(('Default', 'Low', 'High')) g5vlay.addWidget(QLabel('CPU priority')) g5vlay.addWidget(self.combo2) self.combo3 = QComboBox() self.combo3.addItems(('1', '2', '3', '4', '5', '6', '7', '8', '9')) g5vlay.addWidget(QLabel('MultiProcessing Workers')) g5vlay.addWidget(self.combo3) self.outdir = QLineEdit() self.outdir.setStyleSheet("QLineEdit{margin-left:25px}") self.clearButton = QToolButton(self.outdir) self.clearButton.setIcon(QIcon.fromTheme("edit-clear")) self.clearButton.setIconSize(QSize(25, 25)) self.clearButton.setStyleSheet("QToolButton{border:none}") self.clearButton.hide() self.clearButton.clicked.connect(self.outdir.clear) self.outdir.textChanged.connect( lambda: self.clearButton.setVisible(True)) self.clearButton.clicked.connect( lambda: self.clearButton.setVisible(False)) self.outdir.setPlaceholderText('Output Directory') if path.isfile('.nuitka-output-dir.txt'): self.outdir.setText(open('.nuitka-output-dir.txt', 'r').read()) else: self.outdir.setText(path.expanduser("~")) self.completer, self.dirs = QCompleter(self), QDirModel(self) self.dirs.setFilter(QDir.Dirs | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCompletionMode(QCompleter.PopupCompletion) self.completer.popup().setStyleSheet( """border:1px solid #4a4a4a;background:grey; selection-background-color:cyan;selection-color:#000""") self.completer.popup().setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOff) self.outdir.setCompleter(self.completer) self.btn1 = QPushButton(QIcon.fromTheme("document-open"), 'Open' if IS_WIN else '') self.btn1.clicked.connect( lambda: open('.nuitka-output-dir.txt', 'w').write( str( QFileDialog.getExistingDirectory( None, 'Open Output Directory', path.expanduser("~"))))) self.btn1.released.connect(lambda: self.outdir.setText( open('.nuitka-output-dir.txt', 'r').read())) g1vlay.addWidget(QLabel('Output Directory')) g1vlay.addWidget(self.outdir) g1vlay.addWidget(self.btn1) self.target = QLineEdit() self.target.setStyleSheet("QLineEdit{margin-left:25px}") self.clearButton2 = QToolButton(self.target) self.clearButton2.setIcon(QIcon.fromTheme("edit-clear")) self.clearButton2.setIconSize(QSize(25, 25)) self.clearButton2.setStyleSheet("QToolButton{border:none}") self.clearButton2.hide() self.clearButton2.clicked.connect(self.target.clear) self.target.textChanged.connect( lambda: self.clearButton2.setVisible(True)) self.clearButton2.clicked.connect( lambda: self.clearButton2.setVisible(False)) self.target.setPlaceholderText('Target Python App to Binary Compile') self.target.setCompleter(self.completer) self.btn2 = QPushButton(QIcon.fromTheme("document-open"), 'Open' if IS_WIN else '') self.btn2.clicked.connect(lambda: self.target.setText( str( QFileDialog.getOpenFileName( None, "Open", path.expanduser("~"), ';;'.join([ '{}(*.{})'.format(e.upper(), e) for e in ('py', 'pyw', '*') ]))))) g1vlay.addWidget(QLabel('Input File')) g1vlay.addWidget(self.target) g1vlay.addWidget(self.btn2) self.icon, self.icon_label = QLineEdit(), QLabel('Icon File') self.icon.setStyleSheet("QLineEdit{margin-left:25px}") self.clearButton3 = QToolButton(self.icon) self.clearButton3.setIcon(QIcon.fromTheme("edit-clear")) self.clearButton3.setIconSize(QSize(25, 25)) self.clearButton3.setStyleSheet("QToolButton{border:none}") self.clearButton3.hide() self.clearButton3.clicked.connect(self.icon.clear) self.icon.textChanged.connect( lambda: self.clearButton3.setVisible(True)) self.clearButton3.clicked.connect( lambda: self.clearButton3.setVisible(False)) self.icon.setPlaceholderText('Path to Icon file for your App') self.icon.setCompleter(self.completer) self.btn3 = QPushButton(QIcon.fromTheme("document-open"), 'Open' if IS_WIN else '') self.btn3.clicked.connect(lambda: self.icon.setText( str( QFileDialog.getOpenFileName( None, "Open", path.expanduser("~"), ';;'.join([ '{}(*.{})'.format(e.upper(), e) for e in ('ico', 'png', 'bmp', 'svg', '*') ]))))) g1vlay.addWidget(self.icon_label) g1vlay.addWidget(self.icon) g1vlay.addWidget(self.btn3) # Menu Bar inicialization and detail definitions menu_salir = QAction(QIcon.fromTheme("application-exit"), 'Quit', self) menu_salir.setStatusTip('Quit') menu_salir.triggered.connect(exit) menu_minimize = QAction(QIcon.fromTheme("go-down"), 'Minimize', self) menu_minimize.setStatusTip('Minimize') menu_minimize.triggered.connect(lambda: self.showMinimized()) menu_qt = QAction(QIcon.fromTheme("help-about"), 'About Qt', self) menu_qt.setStatusTip('About Qt...') menu_qt.triggered.connect(lambda: QMessageBox.aboutQt(self)) menu_dev = QAction(QIcon.fromTheme("applications-development"), 'Developer Manual PDF', self) menu_dev.setStatusTip('Open Nuitka Developer Manual PDF...') menu_dev.triggered.connect(lambda: call( OPEN + '/usr/share/doc/nuitka/Developer_Manual.pdf.gz', shell=True) ) menu_usr = QAction(QIcon.fromTheme("help-contents"), 'User Docs', self) menu_usr.setStatusTip('Open Nuitka End User Manual PDF...') menu_usr.triggered.connect(lambda: call( OPEN + '/usr/share/doc/nuitka/README.pdf.gz', shell=True)) menu_odoc = QAction(QIcon.fromTheme("help-browser"), 'OnLine Doc', self) menu_odoc.setStatusTip('Open Nuitka on line Documentation pages...') menu_odoc.triggered.connect( lambda: open_new_tab('http://nuitka.net/doc/user-manual.html')) menu_man = QAction(QIcon.fromTheme("utilities-terminal"), 'Man', self) menu_man.setStatusTip('Open Nuitka technical command line Man Pages..') menu_man.triggered.connect( lambda: call('xterm -e "man nuitka"', shell=True)) menu_tra = QAction(QIcon.fromTheme("applications-development"), 'View Nuitka-GUI Source Code', self) menu_tra.setStatusTip('View, study, edit Nuitka-GUI Libre Source Code') menu_tra.triggered.connect(lambda: call(OPEN + __file__, shell=True)) menu_foo = QAction(QIcon.fromTheme("folder"), 'Open Output Dir', self) menu_foo.setStatusTip('Open the actual Output Directory location...') menu_foo.triggered.connect( lambda: call(OPEN + str(self.outdir.text()), shell=True)) menu_pic = QAction(QIcon.fromTheme("camera-photo"), 'Screenshot', self) menu_pic.setStatusTip('Take a Screenshot for Documentation purposes..') menu_pic.triggered.connect( lambda: QPixmap.grabWindow(QApplication.desktop().winId()).save( QFileDialog.getSaveFileName(None, "Save", path.expanduser("~"), 'PNG(*.png)', 'png'))) menu_don = QAction(QIcon.fromTheme("emblem-favorite"), 'Help Nuitka', self) menu_don.setStatusTip('Help the Nuitka Open Source Libre Free Project') menu_don.triggered.connect( lambda: open_new_tab('http://nuitka.net/pages/donations.html')) # movable draggable toolbar self.toolbar = QToolBar(self) self.toolbar.setIconSize(QSize(16, 16)) self.toolbar.toggleViewAction().setText("Show/Hide Toolbar") l_spacer, r_spacer = QWidget(self), QWidget(self) l_spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) r_spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.toolbar.addWidget(l_spacer) self.toolbar.addSeparator() self.toolbar.addActions((menu_salir, menu_minimize, menu_qt, menu_odoc, menu_foo, menu_pic, menu_don)) if not IS_WIN: self.toolbar.addActions((menu_man, menu_dev, menu_tra, menu_usr)) self.toolbar.addSeparator() self.toolbar.addWidget(r_spacer) self.addToolBar(Qt.BottomToolBarArea, self.toolbar) # Bottom Buttons Bar self.buttonBox = QDialogButtonBox(self) self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Close) self.buttonBox.rejected.connect(exit) self.buttonBox.accepted.connect(self.run) self.guimode = QComboBox() self.guimode.addItems(('Full UX / UI', 'Simple UX / UI')) self.guimode.setStyleSheet( """QComboBox{background:transparent;border:0; margin-left:25px;color:gray;text-decoration:underline}""") self.guimode.currentIndexChanged.connect(self.set_guimode) container = QWidget() container_layout = QGridLayout(container) # Y, X container_layout.addWidget(self.guimode, 0, 1) container_layout.addWidget(self.group2, 1, 0) container_layout.addWidget(self.group3, 2, 0) container_layout.addWidget(self.group0, 1, 1) container_layout.addWidget(self.group1, 2, 1) container_layout.addWidget(self.group4, 1, 2) container_layout.addWidget(self.group5, 2, 2) container_layout.addWidget(self.buttonBox, 3, 1) self.setCentralWidget(container) # Paleta de colores para pintar transparente if not A11Y: palette = self.palette() palette.setBrush(QPalette.Base, Qt.transparent) self.setPalette(palette) self.setAttribute(Qt.WA_OpaquePaintEvent, False) def get_fake_tree(self, target): """Return the fake tree.""" try: fake_tree = check_output(NUITKA + ' --dump-xml ' + target, shell=True) except: fake_tree = "ERROR: Failed to get Tree Dump." finally: return fake_tree.strip() def run(self): ' run the actual backend process ' self.treeview_nodes.clear() self.textedit_source.clear() self.output.clear() self.statusBar().showMessage('WAIT!, Working...') target = str(self.target.text()).strip() self.treeview_nodes.setText(self.get_fake_tree(target)) self.textedit_source.setText(open(target, "r").read().strip()) conditional_1 = sys.platform.startswith('linux') conditional_2 = self.combo3.currentIndex() != 2 command_to_run_nuitka = " ".join( ('chrt -i 0' if conditional_1 and conditional_2 else '', NUITKA, '--debug' if self.slider1.value() else '', '--verbose' if self.slider2.value() else '', '--show-progress' if self.slider3.value() else '', '--show-scons --show-modules' if self.slider4.value() else '', '--unstriped' if self.slider5.value() else '', '--trace-execution' if self.slider6.value() else '', '--remove-output' if self.slider7.value() else '', '--no-optimization' if self.slider8.value() else '', '--code-gen-no-statement-lines' if self.slider9.value() else '', '--execute' if self.slider10.value() else '', '--recurse-all' if self.slider1a.value() else '', '--recurse-none' if self.slider2a.value() else '', '--recurse-stdlib' if self.slider3a.value() else '', '--clang' if self.slider4a.value() else '', '--lto' if self.slider5a.value() else '', '--windows-disable-console' if self.slider6a.value() else '', '--windows-target' if self.slider7a.value() else '', '--python-debug' if self.slider8a.value() else '', '--exe' if self.slider9a.value() else '', '--standalone' if self.slider10a.value() else '', '--module' if self.slider11a.value() else '', '--nofreeze-stdlib' if self.slider12a.value() else '', '--mingw' if self.slider13a.value() else '', '--warn-implicit-exceptions' if self.slider11.value() else '', '--execute-with-pythonpath' if self.slider12.value() else '', '--enhanced' if self.slider13.value() else '', '--icon="{}"'.format(self.icon.text()) if self.icon.text() else '', '--python-version={}'.format( self.combo1.currentText()), '--jobs={}'.format( self.combo3.currentText()), '--output-dir="{}"'.format( self.outdir.text()), "{}".format(target))) if DEBUG: print(command_to_run_nuitka) self.process.start(command_to_run_nuitka) if not self.process.waitForStarted() and not IS_WIN: return # ERROR ! self.statusBar().showMessage(__doc__.title()) def _process_finished(self): """finished sucessfully""" self.output.setFocus() self.output.selectAll() def read_output(self): """Read and append output to the log""" self.output.append(str(self.process.readAllStandardOutput())) def read_errors(self): """Read and append errors to the log""" self.output.append(str(self.process.readAllStandardError())) def paintEvent(self, event): """Paint semi-transparent background,animated pattern,background text""" if not A11Y: p = QPainter(self) p.setRenderHint(QPainter.Antialiasing) p.setRenderHint(QPainter.TextAntialiasing) p.setRenderHint(QPainter.HighQualityAntialiasing) p.fillRect(event.rect(), Qt.transparent) # animated random dots background pattern for i in range(4096): x = randint(25, self.size().width() - 25) y = randint(25, self.size().height() - 25) # p.setPen(QPen(QColor(randint(9, 255), 255, 255), 1)) p.drawPoint(x, y) p.setPen(QPen(Qt.white, 1)) p.rotate(40) p.setFont(QFont('Ubuntu', 250)) p.drawText(200, 99, "Nuitka") p.rotate(-40) p.setPen(Qt.NoPen) p.setBrush(QColor(0, 0, 0)) p.setOpacity(0.8) p.drawRoundedRect(self.rect(), 9, 9) p.end() def set_guimode(self): """Switch between simple and full UX""" for widget in (self.group2, self.group3, self.group4, self.group5, self.icon, self.icon_label, self.btn3, self.toolbar, self.statusBar()): widget.hide() if self.guimode.currentIndex() else widget.show()
def __init__(self, params_pipe, number_pipe, data_pipe, mads_pipe, peaks_pipe, probe_path=None, screen_resolution=None): QMainWindow.__init__(self) # Receive parameters. params = params_pipe[0].recv() self._nb_samples = params['nb_samples'] self._sampling_rate = params['sampling_rate'] self._params = { 'nb_samples': self._nb_samples, 'sampling_rate': self._sampling_rate, 'time': { 'min': 10.0, # ms 'max': 1000.0, # ms 'init': 100.0, # ms }, 'voltage': { 'min': 10.0, # µV 'max': 10e+3, # µV 'init': 100.0, # µV }, } self._canvas = VispyCanvas(probe_path=probe_path, params=self._params) central_widget = self._canvas.native # Create controls widgets. label_time = QLabel() label_time.setText(u"time") label_voltage = QLabel() label_voltage.setText(u"voltage") self._dsp_time = QDoubleSpinBox() self._dsp_time.setMinimum(self._params['time']['min']) self._dsp_time.setMaximum(self._params['time']['max']) self._dsp_time.setValue(self._params['time']['init']) self._dsp_time.valueChanged.connect(self._on_time_changed) self._dsp_voltage = QDoubleSpinBox() self._dsp_voltage.setMinimum(self._params['voltage']['min']) self._dsp_voltage.setMaximum(self._params['voltage']['max']) self._dsp_voltage.setValue(self._params['voltage']['init']) self._dsp_voltage.valueChanged.connect(self._on_voltage_changed) label_time_unit = QLabel() label_time_unit.setText(u"ms") label_voltage_unit = QLabel() label_voltage_unit.setText(u"µV") spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) # Create controls grid. grid = QGridLayout() # # Add time row. grid.addWidget(label_time, 0, 0) grid.addWidget(self._dsp_time, 0, 1) grid.addWidget(label_time_unit, 0, 2) # # Add voltage row. grid.addWidget(label_voltage, 1, 0) grid.addWidget(self._dsp_voltage, 1, 1) grid.addWidget(label_voltage_unit, 1, 2) # # Add spacer. grid.addItem(spacer) # Create controls group. controls_group = QGroupBox() controls_group.setLayout(grid) # Create controls dock. dock = QDockWidget() dock.setWidget(controls_group) dock.setWindowTitle("Controls") # Create info widgets. label_time = QLabel() label_time.setText(u"time") self._label_time_value = QLineEdit() self._label_time_value.setText(u"0") self._label_time_value.setReadOnly(True) self._label_time_value.setAlignment(Qt.AlignRight) label_time_unit = QLabel() label_time_unit.setText(u"s") info_buffer_label = QLabel() info_buffer_label.setText(u"buffer") self._info_buffer_value_label = QLineEdit() self._info_buffer_value_label.setText(u"0") self._info_buffer_value_label.setReadOnly(True) self._info_buffer_value_label.setAlignment(Qt.AlignRight) info_buffer_unit_label = QLabel() info_buffer_unit_label.setText(u"") info_probe_label = QLabel() info_probe_label.setText(u"probe") info_probe_value_label = QLineEdit() info_probe_value_label.setText(u"{}".format(probe_path)) info_probe_value_label.setReadOnly(True) # TODO place the following info in another grid? info_probe_unit_label = QLabel() info_probe_unit_label.setText(u"") info_spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) # Create info grid. info_grid = QGridLayout() # # Time row. info_grid.addWidget(label_time, 0, 0) info_grid.addWidget(self._label_time_value, 0, 1) info_grid.addWidget(label_time_unit, 0, 2) # # Buffer row. info_grid.addWidget(info_buffer_label, 1, 0) info_grid.addWidget(self._info_buffer_value_label, 1, 1) info_grid.addWidget(info_buffer_unit_label, 1, 2) # # Probe row. info_grid.addWidget(info_probe_label, 2, 0) info_grid.addWidget(info_probe_value_label, 2, 1) info_grid.addWidget(info_probe_unit_label, 2, 2) # # Spacer. info_grid.addItem(info_spacer) # Create info group. info_group = QGroupBox() info_group.setLayout(info_grid) # Create info dock. info_dock = QDockWidget() info_dock.setWidget(info_group) info_dock.setWindowTitle("Info") # Create thread. thread = Thread(number_pipe, data_pipe, mads_pipe, peaks_pipe) thread.number_signal.connect(self._number_callback) thread.reception_signal.connect(self._reception_callback) thread.start() # Add dockable windows. self.addDockWidget(Qt.LeftDockWidgetArea, dock) self.addDockWidget(Qt.LeftDockWidgetArea, info_dock) # Set central widget. self.setCentralWidget(central_widget) # Set window size. if screen_resolution is not None: screen_width = screen_resolution.width() screen_height = screen_resolution.height() self.resize(screen_width, screen_height) # Set window title. self.setWindowTitle("SpyKING Circus ORT - Read 'n' Qt display") print("#####") # TODO remove?
class Main(plugin.Plugin): " Main Class " def initialize(self, *args, **kwargs): " Init Main Class " super(Main, self).initialize(*args, **kwargs) self.completer, self.dirs = QCompleter(self), QDirModel(self) self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCompletionMode(QCompleter.PopupCompletion) self.process, self.mainwidget = QProcess(), QTabWidget() self.process.readyReadStandardOutput.connect(self.readOutput) self.process.readyReadStandardError.connect(self.readErrors) self.process.finished.connect(self._process_finished) self.process.error.connect(self._process_finished) self.mainwidget.tabCloseRequested.connect(lambda: self.mainwidget.setTabPosition(1) if self.mainwidget.tabPosition() == 0 else self.mainwidget.setTabPosition(0)) self.mainwidget.setStyleSheet('QTabBar{font-weight:bold;}') self.mainwidget.setMovable(True) self.mainwidget.setTabsClosable(True) self.dock, self.scrollable = QDockWidget(), QScrollArea() self.scrollable.setWidgetResizable(True) self.scrollable.setWidget(self.mainwidget) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.dock.setWidget(self.scrollable) self.locator.get_service('misc').add_widget(self.dock, QIcon.fromTheme("face-sad"), __doc__) self.tab1, self.tab2, self.tab3 = QGroupBox(), QGroupBox(), QGroupBox() self.tab4, self.tab5, self.tab6 = QGroupBox(), QGroupBox(), QGroupBox() for a, b in ((self.tab1, 'Basics'), (self.tab2, 'Coverage'), (self.tab3, 'Extensions'), (self.tab5, 'Regex'), (self.tab4, 'Paths'), (self.tab6, 'Run')): a.setTitle(b) a.setToolTip(b) self.mainwidget.addTab(a, QIcon.fromTheme("face-sad"), b) QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock ).clicked.connect(lambda: QMessageBox.information(self.dock, __doc__, ''.join((__doc__, __version__, __license__, 'by', __author__)))) groupl, groupr, co = QWidget(), QWidget(), QGroupBox() self.qckb1 = QCheckBox('Open target directory later') self.qckb2 = QCheckBox('Save a LOG file to target later') self.qckb3 = QCheckBox('Verbose operation') self.qckb4 = QCheckBox('Force Stop on Error') self.qckb5 = QCheckBox('Scan Executable files for Tests') vboxgl, vboxgr = QVBoxLayout(groupl), QVBoxLayout(groupr) for a in (self.qckb1, self.qckb2, self.qckb3, self.qckb4, self.qckb5): vboxgl.addWidget(a) a.setToolTip(a.text()) self.qckb6 = QCheckBox('No Byte Compile to .PYC or Delete .PYC later') self.qckb7 = QCheckBox('Dont touch sys.path when running tests') self.qckb8 = QCheckBox('Traverse all paths of a package') self.qckb9 = QCheckBox('Dont capture STDOUT, print STDOUT on the fly') self.qckb10 = QCheckBox('Clear all Logging handlers') for a in (self.qckb6, self.qckb7, self.qckb8, self.qckb9, self.qckb10): vboxgr.addWidget(a) a.setToolTip(a.text()) vboxcon, self.framew = QHBoxLayout(co), QComboBox() [vboxcon.addWidget(a) for a in (groupl, groupr)] self.chrt = QCheckBox('LOW CPU priority for Backend Process') self.framew.addItems(['nosetests', 'PyTest', 'DocTest', 'Unittest', 'Django_Test', 'Django-Nose', 'None']) self.framew.currentIndexChanged.connect(lambda: #FIXME refactor for 3 QMessageBox.information(self.dock, __doc__, '<b>Only Nose for now')) self.framew.currentIndexChanged.connect(lambda: #FIXME refactor for 3 self.framew.setCurrentIndex(0)) vboxg1 = QVBoxLayout(self.tab1) for each_widget in (QLabel('<b>Framework'), self.framew, self.chrt, co): vboxg1.addWidget(each_widget) self.t2ck1, self.t2sp1 = QCheckBox('Activate Coverage'), QSpinBox() self.t2ck2 = QCheckBox('Erase previously collected Coverage before run') self.t2ck3 = QCheckBox('Include all tests modules in Coverage reports') self.t2ck4 = QCheckBox('Include all python files on working directory') self.t2ck5 = QCheckBox('Produce HTML Coverage reports information') self.t2ck6 = QCheckBox('Include Branch Coverage in Coverage reports') self.t2sp1.setRange(10, 90) self.t2sp1.setValue(75) vboxg2 = QVBoxLayout(self.tab2) for each_widget in (QLabel('<b>Min Percentage'), self.t2sp1, self.t2ck1, self.t2ck2, self.t2ck3, self.t2ck4, self.t2ck5, self.t2ck6): vboxg2.addWidget(each_widget) groupi, groupd, vbxg3 = QGroupBox(), QGroupBox(), QHBoxLayout(self.tab3) vboxgi, vboxgd = QVBoxLayout(groupi), QVBoxLayout(groupd) self.t3ck1 = QCheckBox('Activate DocTest to find and run doctests') self.t3ck2 = QCheckBox('Look for any doctests in tests modules too') self.t3ck3 = QCheckBox('Activate isolation (Do Not use with Coverage!)') self.t3ck4 = QCheckBox('Use Detailed Errors, evaluate failed asserts') for a in (self.t3ck1, self.t3ck2, self.t3ck3, self.t3ck4): vboxgi.addWidget(a) a.setToolTip(a.text()) self.t3ck5 = QCheckBox('Disable special handling of SkipTest exception') self.t3ck6 = QCheckBox('Run the tests that failed in the last test run') self.t3ck7 = QCheckBox('Use AllModules, Collect tests from all modules') self.t3ck8 = QCheckBox('Collect tests names only, do Not run any tests') for a in (self.t3ck5, self.t3ck6, self.t3ck7, self.t3ck8): vboxgd.addWidget(a) a.setToolTip(a.text()) [vbxg3.addWidget(a) for a in (groupi, groupd)] self.t4le1, self.t4le2 = QLineEdit(), QLineEdit(path.expanduser("~")) self.t4le1.setCompleter(self.completer) self.t4le2.setCompleter(self.completer) self.t4le1.setPlaceholderText(' /full/path/to/a/folder/ ') self.t4le2.setPlaceholderText(' /full/path/to/a/folder/ ') le1b = QPushButton(QIcon.fromTheme("folder-open"), 'Open') le1b.setMinimumSize(50, 50) le1b.clicked.connect(lambda: self.t4le1.setText( QFileDialog.getExistingDirectory(None, '', path.expanduser("~")))) le2b = QPushButton(QIcon.fromTheme("folder-open"), 'Open') le2b.clicked.connect(lambda: self.t4le2.setText( QFileDialog.getExistingDirectory(None, '', path.expanduser("~")))) vboxg4 = QVBoxLayout(self.tab4) for a in (QLabel('<b>Directory to look for Tests'), self.t4le1, le1b, QLabel('<b>Directory to generate HTML Coverage'), self.t4le2, le2b): vboxg4.addWidget(a) a.setToolTip(a.text()) self.t5le1 = QLineEdit(r'(?:^|[\b_\./-])[Tt]est') self.t5le2 = QLineEdit() self.t5le3, vboxg5 = QLineEdit(), QVBoxLayout(self.tab5) r = QPushButton('Reset') r.clicked.connect(lambda: self.t5le1.setText(r'(?:^|[\b_\./-])[Tt]est')) for a in (QLabel('<b>Matching Name Regex to be test'), self.t5le1, r, QLabel('<b>Force Include Regex Tests'), self.t5le2, QLabel('<b>Force Exclude Regex Tests'), self.t5le3): vboxg5.addWidget(a) a.setToolTip(a.text()) self.output = QTextEdit(''' Engineering is the art of making what you want from things you can get. -Dhobi''') self.runbtn = QPushButton(QIcon.fromTheme("face-sad"), 'Start Testing!') self.runbtn.setMinimumSize(75, 50) self.runbtn.clicked.connect(self.run) glow = QGraphicsDropShadowEffect(self) glow.setOffset(0) glow.setBlurRadius(99) glow.setColor(QColor(99, 255, 255)) self.runbtn.setGraphicsEffect(glow) self.kbt = QPushButton(QIcon.fromTheme("application-exit"), 'Kill') self.kbt.clicked.connect(lambda: self.process.kill()) vboxg6 = QVBoxLayout(self.tab6) for each_widget in (QLabel('Logs'), self.output, self.runbtn, self.kbt): vboxg6.addWidget(each_widget) [a.setChecked(True) for a in (self.chrt, self.qckb2, self.qckb3, self.qckb10, self.t2ck1, self.t2ck2, self.t2ck5, self.t3ck1, self.t3ck4)] self.mainwidget.setCurrentIndex(4) def readOutput(self): """Read and append output to the logBrowser""" self.output.append(str(self.process.readAllStandardOutput())) def readErrors(self): """Read and append errors to the logBrowser""" self.output.append(str(self.process.readAllStandardError())) def run(self): """Main function calling vagrant to generate the vm""" if not len(self.t4le1.text()): QMessageBox.information(self.dock, __doc__, '<b style="color:red">ERROR: Target Folder can not be Empty !') return self.output.clear() self.output.append('INFO: OK: Starting at {}'.format(datetime.now())) self.runbtn.setDisabled(True) #nose = True if self.framew.currentText() in 'nosetests' else False cmd = ' '.join(('chrt -i 0' if self.chrt.isChecked() else '', # tab 1 self.framew.currentText(), '--verbose' if self.qckb3.isChecked() else '--quiet', '--stop' if self.qckb4.isChecked() else '', '--exe' if self.qckb5.isChecked() else '--noexe', '--no-byte-compile' if self.qckb6.isChecked() else '', '--no-path-adjustment' if self.qckb7.isChecked() else '', '--traverse-namespace' if self.qckb8.isChecked() else '', '--nocapture' if self.qckb9.isChecked() else '', '--logging-clear-handlers' if self.qckb10.isChecked() else '', # tab 2 '--with-coverage' if self.t2ck1.isChecked() else '', '--cover-erase' if self.t2ck2.isChecked() else '', '--cover-tests' if self.t2ck3.isChecked() else '', '--cover-inclusive' if self.t2ck4.isChecked() else '', '--cover-html' if self.t2ck5.isChecked() else '--cover-xml', '--cover-branches' if self.t2ck6.isChecked() else '', '--cover-min-percentage={}'.format(self.t2sp1.value()), # tab 3 '--with-doctest' if self.t3ck1.isChecked() else '', '--doctest-tests' if self.t3ck2.isChecked() else '', '--with-isolation' if self.t3ck3.isChecked() else '', '--detailed-errors' if self.t3ck4.isChecked() else '', '--no-skip' if self.t3ck5.isChecked() else '', '--failed' if self.t3ck6.isChecked() else '', '--all-modules' if self.t3ck7.isChecked() else '', '--collect-only' if self.t3ck8.isChecked() else '', # tab 4 '--where="{}"'.format(self.t4le1.text()), '--cover-html-dir="{}"'.format(self.t4le2.text()) if self.t2ck5.isChecked() else '--cover-xml-file={}'.format(path.join(self.t4le2.text(), 'coverage_ninja.xml')), # tab 5 '--match="{}"'.format(self.t5le1.text().encode('utf-8')) if len(self.t5le1.text()) else '', '--include="{}"'.format(self.t5le2.text()) if len(self.t5le2.text()) else '', '--exclude="{}"'.format(self.t5le3.text()) if len(self.t5le3.text()) else '', )) self.output.append('INFO: OK: Command: {}'.format(cmd)) with open(path.join(self.t4le2.text(), 'tests_run_ninja.sh'), 'w') as f: self.output.append('INFO: OK : Writing tests_run_ninja.sh') f.write('#!/usr/bin/env bash\n# -*- coding: utf-8 -*-\n\n' + cmd) try: chmod(path.join(self.t4le2.text(), 'tests_run_ninja.sh'), 0775) except: chmod(path.join(self.t4le2.text(), 'tests_run_ninja.sh'), 0o775) self.output.append('INFO: OK: Running Tests !') self.process.start(cmd) if not self.process.waitForStarted(): self.output.append('ERROR: FAIL: Unkown Error !') self.runbtn.setEnabled(True) return self.runbtn.setEnabled(True) def _process_finished(self): """finished sucessfully""" self.output.append('INFO: OK: Finished at {}'.format(datetime.now())) if self.qckb2.isChecked() is True: with open(path.join(self.t4le2.text(), 'test_ninja.log'), 'w') as f: self.output.append('INFO: OK: Writing .LOG') f.write(self.output.toPlainText()) if self.qckb1.isChecked() is True: self.output.append('INFO:Opening Target Folder') try: startfile(self.t4le2.text()) except: Popen(["xdg-open", self.t4le2.text()]) def finish(self): ' clear when finish ' self.process.kill()
def setWindowTitle(self, text): QDockWidget.setWindowTitle(self, text) self.windowTitleChanged.emit(text)
class MSMainWindow(QMainWindow): """Gui of the main window""" # MAX_RECENT_FILES = 10 # start putting links spyder numpy scipy et tutti quanti links = ( "http://numpy.scipy.org/", "http://packages.python.org/spyder/", "http://www.riverbankcomputing.co.uk/software/pyqt/intro", ) pluginPath = path.normcase("pluginmanager/plugins/") def __init__(self, availablePlugins): """ Constructor with all the models needed setup menus """ QMainWindow.__init__(self) self.setDockOptions(QMainWindow.VerticalTabs | QMainWindow.AnimatedDocks) self.plugins = availablePlugins self.pluginsInst = [] settings = QSettings( "INRA/INSA", "-".join([QApplication.instance().APPLICATION_NAME_STR, QApplication.instance().VERSION_STR]) ) self.recentFiles = list(settings.value("RecentFiles").toStringList()) self.setStyleSheet(stylesheet) self.pipeline = MSPipelineToolBar("Pipeline toolbar", parent=self) self.addToolBar(0x1, self.pipeline) self._setupModels() self._setupUi() self._setupMenus() def _setupModels(self): """ Warning:Causes segfault when horizontal labels set to True on aura peu etre a la fin un model par sampleList c'est ce qui parait le plus logique """ # drag and drop table sample self.sampleModel = QStandardItemModel(self) self.sampleModel.setHorizontalHeaderLabels(["Sample", "Class"]) # treeView1 self.spectraModel = QStandardItemModel(self) # treeview2 self.peakModel = QStandardItemModel(self) # treeview3 self.clusterModel = QStandardItemModel(self) def _setupMenus(self): # file self.fileMenu = QMenu("&File") self.fileMenu.setTearOffEnabled(True) self.op = QMenu("&Open...", self.fileMenu) self.op.setIcon(QIcon(path.normcase("gui/icons/fileopen.png"))) open_ = QAction("&Open rawfiles", self) open_.setToolTip("Open an mzXML or netCDF file") open_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_O)) open_icon = QIcon(path.normcase("gui/icons/fileopen.png")) open_.setIcon(open_icon) self.op.addAction(open_) load_ = QAction("&Open projects...", self) load_.setToolTip("load binary file containing saved objects") load_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_S)) load_icon = QIcon(QPixmap(path.normcase("gui/icons/project_open.png"))) load_.setIcon(load_icon) self.op.addAction(load_) self.fileMenu.addMenu(self.op) save_ = QAction("&Save...", self) save_.setToolTip("save the actual application model") save_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_S)) save_icon = QIcon(path.normcase("gui/icons/save_all.png")) save_.setIcon(save_icon) self.fileMenu.addAction(save_) pkl = QAction("&load a peaklist", self) # TODO:load peaklist pkl.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_P)) pkl.setToolTip("load a peaklist and process it") pkl.setIcon(QIcon(path.normcase("gui/icons/featuredetect.png"))) self.fileMenu.addAction(pkl) convert_ = QAction("&Convert...", self) convert_.setEnabled(False) convert_.setToolTip("Convert a .wiff file if Analyst(c) is installed") convert_icon = QIcon(path.normcase("gui/icons/goto.png")) convert_.setIcon(convert_icon) self.fileMenu.addAction(convert_) a = self.fileMenu.addAction(QIcon(path.normcase("gui/icons/process.png")), "&Launch a batch") a.setEnabled(False) b = self.fileMenu.addAction(QIcon(path.normcase("gui/icons/process.png")), "&Merge") b.setToolTip("Merge MRM file") # b.setEnabled(False) self.fileMenu.addSeparator() # # for i in xrange(self.MAX_RECENT_FILES): # a = QAction('', self) # a.setVisible(False) # self.fileMenu.addAction(a) # # for i in xrange(min(self.MAX_RECENT_FILES, len(self.recentFiles))): # self.fileMenu.actions()[5+i].setVisible(True) # self.fileMenu.actions()[5+i].setText(self.recentFiles[i].split('/')[-1]) exit_action = QAction("&Exit", self) exit_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q)) exit_action.setIcon(QIcon(QPixmap(path.normcase("gui/icons/exit.png")))) self.fileMenu.addAction(exit_action) self.menuBar().addMenu(self.fileMenu) self.editMenu = QMenu("&Edit") self.editMenu.setTearOffEnabled(True) self.editMenu.addAction(QIcon(path.normcase("gui/icons/edit_undo.png")), "&Undo...") self.editMenu.addAction(QIcon(path.normcase("gui/icons/edit_redo.png")), "&Redo...") self.editMenu.actions()[0].setEnabled(False) self.editMenu.actions()[1].setEnabled(False) self.editMenu.addSeparator() self.editMenu.addAction(QIcon(path.normcase("gui/icons/run.png")), "&Preferences") self.exportMenu = QMenu("&Export...") self.exportMenu.setIcon(QIcon(path.normcase("gui/icons/file_export.png"))) self.exportMenu.addAction("&Peaklist") self.exportMenu.addAction("&Clusters intensity matrix") self.editMenu.addMenu(self.exportMenu) self.menuBar().addMenu(self.editMenu) # view self.viewMenu = QMenu("&View") self.viewMenu.setTearOffEnabled(True) self.viewMenu.addAction( QIcon(path.normcase("gui/icons/window_duplicate")), "&Cascade View", self.mdiArea.cascadeSubWindows, QKeySequence(Qt.CTRL + Qt.Key_K), ) self.viewMenu.addAction( QIcon(path.normcase("gui/icons/view_icon")), "&Title View", self.mdiArea.tileSubWindows, QKeySequence(Qt.CTRL + Qt.Key_N), ) self.viewMenu.addAction( QIcon(path.normcase("gui/icons/stop_process.png")), "&Close all subWindows", self.mdiArea.closeAllSubWindows, QKeySequence(Qt.CTRL + Qt.Key_W), ) self.plotting = QMenu("&Plotting...") self.plotting.setIcon(QIcon(QPixmap(path.normcase("gui/icons/plot.png")))) self.plotting.addAction("&3D Plot") # self.plotting.addAction("&Cytoscape web") self.plotting.addAction("&Spectrogram Plot") # self.multiplePlot = QAction("&Visualize Raw/Treated Data", self) # self.multiplePlot.setCheckable(True) # self.multiplePlot.setEnabled(False) # self.sub_plot_.addAction(self.multiplePlot) self.viewMenu.addMenu(self.plotting) self.viewMenu.addSeparator() self.show_hide = QMenu("&Show/Hide") m = self.createPopupMenu() m.setTitle("&Show/Hide") self.viewMenu.addMenu(m) # self.pref = QMenu("&Preferences") # self.pref.addAction(self.multiplePlot) # self.viewMenu.addMenu(self.pref) self.menuBar().addMenu(self.viewMenu) # algorithm self.algoMenu = QMenu("&Algorithm") self.algoMenu.setTearOffEnabled(True) self.preProcessing = QMenu("&PreProcessing(experimental)") self.preProcessing.addAction("&Smoothing raw data...") self.preProcessing.addAction("&Cut off raw data...") self.preProcessing.addAction("&Calibration (mz dimension)") self.preProcessing.addAction("&Resize sample...") self.algoMenu.addMenu(self.preProcessing) self.peakPickingMenu = QMenu("&Peack Picking & Alignement(XCMS)", self) self.peakPickingMenu.setIcon(QIcon(path.normcase("gui/icons/pickedpeakicon.png"))) matched = QAction("&MatchedFiltered", self) matched.setIcon(QIcon(path.normcase("gui/icons/RLogo"))) matched.setToolTip("Peak Detection and Integration using MatchedFiltered algorithm") self.peakPickingMenu.addAction(matched) centwave = QAction("&CentWave", self) centwave.setIcon(QIcon(path.normcase("gui/icons/RLogo"))) centwave.setToolTip("Peak Detection and Integration using CentWave algorithm") self.peakPickingMenu.addAction(centwave) # peak_.setShortcut(.QKeySequence(CTRL + Key_P)) # peak_icon=.QIcon(.QPixmap(path.normcase("gui/icons/pickedpeakicon.png"))) # peak_.setIcon(peak_icon) self.algoMenu.addMenu(self.peakPickingMenu) self.alignment = QMenu("&Alignment") self.alignment.setIcon(QIcon(path.normcase("gui/icons/format_indent_more.png"))) self.alignment.addAction("&Polynomial fitting(exp)") self.alignment.addAction("&DynamicTimeWarping") self.alignment.addAction("&ObiWarp") self.alignment.actions()[2].setEnabled(False) self.algoMenu.addMenu(self.alignment) self.algoMenu.addAction("Normalization") clust_ = QAction("&Clustering", self) clust_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_L)) clust_icon = QIcon(QPixmap(path.normcase("gui/icons/cluster.png"))) clust_.setIcon(clust_icon) self.algoMenu.addAction(clust_) id_ = QAction("&Identification", self) id_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_I)) id_.setToolTip("Try to identify peaks with several methods") id_.setIcon(QIcon(QPixmap(path.normcase("gui/icons/findcompound.png")))) self.algoMenu.addAction(id_) self.menuBar().addMenu(self.algoMenu) # tools self.toolsMenu = QMenu("&Tools") self.toolsMenu.setTearOffEnabled(True) web = QAction("&Web Browser", self) web.setIcon(QIcon(QPixmap(path.normcase("gui/icons/applications_internet.png")))) self.toolsMenu.addAction(web) # cyto = QAction("&cytoscape", self) # cyto_icon =QIcon(QPixmap(path.normcase("gui/icons/cytoscape.jpeg"))) # cyto.setIcon(cyto_icon) # self.toolsMenu.addAction(cyto) editor = QAction("&Editor", self) editor.setIcon(QIcon(QPixmap(path.normcase("gui/icons/document_sign.png")))) self.toolsMenu.addAction(editor) pet = QAction("&Short Periodic Table", self) pet.setIcon(QIcon(QPixmap(path.normcase("gui/icons/pet.jpg")))) self.toolsMenu.addAction(pet) self.menuBar().addMenu(self.toolsMenu) # plugins self.pluginMenu = QMenu("&Plugins") self.pluginMenu.setTearOffEnabled(True) instPl = QAction("&Install a plugin", self) instPl.setIcon(QIcon(path.normcase("gui/icons/pluginInstall.png"))) self.pluginMenu.addAction(instPl) self.launchingMenu = QMenu("&Launch PLugins", self) self.launchingMenu.setIcon(QIcon(path.normcase("gui/icons/plugin"))) for plug in self.plugins: # fullname="".join([self.pluginPath, str(plug)]) mod = imp.load_source(self.__module__, plug) if mod.autoActivation: qApp = QApplication.instance() name = getattr(mod, "className") cls = getattr(mod, name) p = cls(qApp.model, self, parent=self) # p=qApp.pluginManager.loadPlugin(qApp.model, self, plug.split('/')[-1]) self.pluginsInst.append(p) else: self.launchingMenu.addAction(plug.split("/")[-1]) self.pluginMenu.addMenu(self.launchingMenu) self.pluginMenu.addAction(QIcon(path.normcase("gui/icons/process_stop.png")), "&Remove loaded Plugin") self.menuBar().addMenu(self.pluginMenu) # about self.aboutMenu = QMenu("&About") self.aboutMenu.setTearOffEnabled(True) metms = QAction(QIcon(path.normcase("gui/icons/deluge.png")), "&about metMS...", self) self.aboutMenu.addAction(metms) pyqt = QAction("&about PyQt4...", self) pyqt_icon = QIcon(QPixmap(path.normcase("gui/icons/logo_QT4.png"))) pyqt.setIcon(pyqt_icon) self.aboutMenu.addAction(pyqt) metms = QAction("&metMS Documentation", self) metms_icon = QIcon(QPixmap(path.normcase("gui/icons/deluge.png"))) metms.setIcon(metms_icon) self.aboutMenu.addAction(metms) self.menuBar().addMenu(self.aboutMenu) def _setupUi(self, background=None): """ Make the GUI """ # mdi self.mdiArea = MSMdiArea(self) self.mdiArea.setBackground(QBrush(QPixmap(path.normcase("gui/icons/blac2.png")))) # QColor(Qt.blue).darker())) self.setCentralWidget(self.mdiArea) # sample dock widget self.sampleDockWidget = QDockWidget("Samples", self) # sampleWidget = QWidget() self.sampleTableView = MSDragFromTableView() self.sampleTableView.setModel(self.sampleModel) self.sampleTableView.setSelectionBehavior(1) self.sampleTableView.verticalHeader().hide() self.sampleTableView.verticalHeader().setDefaultSectionSize(15) self.sampleTableView.horizontalHeader().setDefaultSectionSize(150) self.sampleDockWidget.setWidget(self.sampleTableView) # sampleWidget) self.sampleDockWidget.visible = True # workflow dock self.workflowDockWidget = QDockWidget("Visualizer", self) self.workflowDockWidget.visible = True a = QWidget(self) v = QVBoxLayout(a) q = QToolBar() # self.workingSample = QLabel("Working Sample:None") # q.addWidget(self.workingSample) q.addWidget(QLabel("ppm :")) self.ppmEditer = QDoubleSpinBox() self.usePpm = QCheckBox("use ?") q.addWidget(self.ppmEditer) q.addWidget(self.usePpm) q.addSeparator() self.removeButton = QToolButton(self) self.removeButton.setIcon(QIcon(path.normcase("gui/icons/delete.png"))) q.addWidget(self.removeButton) self.markAsGood = QAction(QIcon(path.normcase("gui/icons/button_ok.png")), "mark peak as good", self) self.markAsBad = QAction(QIcon(path.normcase("gui/icons/stop.png")), "mark peak as bad", self) self.hideItem = QAction(QIcon(path.normcase("gui/icons/list_remove.png")), "Hide Item", self) q.addAction(self.markAsGood) q.addAction(self.markAsBad) q.addAction(self.hideItem) v.addWidget(q) self.tabWidget = QTabWidget() self.tab = QWidget() verticalLayout = QVBoxLayout(self.tab) self.treeView = MSToDropTableView() self.treeView.verticalHeader().setDefaultSectionSize(20) self.treeView.setModel(self.spectraModel) self.spectraLabel = QLabel("Sample: None") verticalLayout.addWidget(self.treeView) verticalLayout.addWidget(self.spectraLabel) self.tabWidget.addTab(self.tab, QIcon(path.normcase("gui/icons/spectrumicon.png")), "Spectra") self.tab_2 = QWidget() verticalLayout_4 = QVBoxLayout(self.tab_2) self.treeView_2 = MSToDropTableView() # MSTreeView(self.tab_2)# QTableView(self)# self.treeView_2.verticalHeader().setDefaultSectionSize(20) self.treeView_2.setModel(self.peakModel) self.peakLabel = QLabel("Sample: None") verticalLayout_4.addWidget(self.treeView_2) verticalLayout_4.addWidget(self.peakLabel) self.tabWidget.addTab(self.tab_2, QIcon(path.normcase("gui/icons/peakicon.png")), "Peaks List") self.tab_3 = QWidget() verticalLayout_5 = QVBoxLayout(self.tab_3) self.treeView_3 = MSToDropTreeView() self.treeView_3.setAnimated(True) self.treeView_3.setModel(self.clusterModel) self.clusterLabel = QLabel("Sample: None") verticalLayout_5.addWidget(self.treeView_3) verticalLayout_5.addWidget(self.clusterLabel) self.tabWidget.addTab(self.tab_3, QIcon(path.normcase("gui/icons/clustering.png")), "Clusters") self.tabWidget.setCurrentIndex(0) for l in (self.spectraLabel, self.peakLabel, self.clusterLabel): l.setAutoFillBackground(True) v.addWidget(self.tabWidget) self.workflowDockWidget.setWidget(a) self.addDockWidget(Qt.DockWidgetArea(0x2), self.workflowDockWidget) from gui.MetBaseGui import MSIsoCalculator self.isoCalc = MSIsoCalculator(self) self.isoCalcDockWidget = QDockWidget("isotopes calculation", self) self.isoCalcDockWidget.setWidget(self.isoCalc) self.addDockWidget(Qt.DockWidgetArea(0x2), self.isoCalcDockWidget) self.isoCalcDockWidget.setVisible(False) self.isoCalcDockWidget.visible = False from gui.MetBaseGui import FormulaGenerator self.generator = FormulaGenerator(self) self.generatorDockWidget = QDockWidget("formula generator", self) self.generatorDockWidget.setWidget(self.generator) self.addDockWidget(Qt.DockWidgetArea(0x2), self.generatorDockWidget) self.generatorDockWidget.setVisible(False) self.generatorDockWidget.visible = False self.compoundTreeView = MSCompoundTreeView(self) self.compoundDockWidget = QDockWidget("Compounds", self) self.compoundDockWidget.setWidget(self.compoundTreeView) self.addDockWidget(Qt.DockWidgetArea(0x2), self.compoundDockWidget) self.compoundDockWidget.setVisible(False) self.compoundDockWidget.visible = False self.comparativeTableView = QTableView(self) self.comparativeTableView.horizontalHeader().setStretchLastSection(True) self.comparativeTableView.verticalHeader().setDefaultSectionSize(20) self.comparativeDock = QDockWidget("Comparative View", self) self.comparativeDock.setWidget(self.comparativeTableView) self.addDockWidget(Qt.DockWidgetArea(0x8), self.comparativeDock) self.comparativeDock.setVisible(False) self.comparativeDock.visible = False self.tabifyDockWidget(self.compoundDockWidget, self.isoCalcDockWidget) self.tabifyDockWidget(self.isoCalcDockWidget, self.workflowDockWidget) self.tabifyDockWidget(self.workflowDockWidget, self.generatorDockWidget) # set the end # WARNING: possible that the internal shell widget cause random segfault # with the error of QObject::killTimers...? not sure ! self.shell = QWidget() # InternalShell(namespace={'metms': QApplication.instance()}, # parent=self, # multithreaded=False) self.shellDock = QDockWidget("Python Shell", self) self.shellDock.setWindowIcon(QIcon(path.normcase("gui/icons/stop.png"))) self.shellDock.setWidget(self.shell) self.shellDock.setMinimumWidth(255) self.shellDock.visible = True self.addDockWidget(0x2, self.shellDock) self.addDockWidget(0x2, self.sampleDockWidget) self.tabifyDockWidget(self.shellDock, self.sampleDockWidget) self.pb = QProgressBar(self) self.pb.setMaximumWidth(245) self.stopProcess = QToolButton(self) self.stopProcess.setIcon(QIcon(path.normcase("gui/icons/process_stop.png"))) m = QMenu() # self.connect(m, SIGNAL('triggered(QAction*'), QApplication.instance().taskManager.abortByName) self.stopProcess.setMenu(m) self.stopProcess.setPopupMode(1) # Menu Button # self.connect(self.stopProcess, SIGNAL("clicked()"), self.stopThread) self.statusBar().addPermanentWidget(self.stopProcess) self.statusBar().addPermanentWidget(self.pb) def updateStopProcessMenu(self): """ update the menu of the stop process button, based directly on the processes stored by the task manager """ self.stopProcess.menu().clear() for c in QApplication.instance().taskManager: self.stopProcess.menu().addAction(c.title) # QApplication.instance().taskManager.abort(QApplication.instance().taskManager[-1]) def addMdiSubWindow(self, plot, title="", showMaximized=False): """ Allow addition of new window in the mdiarea """ win = self.mdiArea.addSubWindow(plot) # print "widget parent", plot.parent() win.setAttribute(Qt.WA_DeleteOnClose) # win.connect(win, SIGNAL('destroyed(QObject *)'), self.testdestroy) # plot.setParent(win) win.setWindowTitle(title) if showMaximized: win.showMaximized() else: win.resize(400, 300) win.show() return win def updateTreeView(self): """ Tree View update switch spectre/chromato """ if self.treeView.model() == self.spectraModel: self.treeView.setModel(self.chromaModel) self.tabWidget.setTabText(0, "Chroma") else: self.treeView.setModel(self.spectraModel) # self.treeView.setSelectionMode(1) self.tabWidget.setTabText(0, "Spectra") def addTreeViewModel(self, model1, model2): """Add a model """ self.chromaModel.appendRow(model1) self.spectraModel.appendRow(model2) def _actionHovered(self, action): """emulate tooltip cause they do not work that much""" tip = action.toolTip() QToolTip.showText(QCursor.pos(), tip) def showErrorMessage(self, title, string): QMessageBox.critical(self, title, string, 0, 0) def showWarningMessage(self, title, string): return QMessageBox.warning(self, title, string, QMessageBox.Ok | QMessageBox.Cancel) def showInformationMessage(self, title, string): QMessageBox.information(self, title, string, 0) def updateProgressBar(self, i): """update the value of the progress bar for all the treatment""" self.pb.setValue(min(i, 100)) def to_indetermined_mode(self): self.pb.setMaximum(0) def to_determined_mode(self): self.pb.setMaximum(100) def showInStatusBar(self, string, time=5000): self.statusBar().showMessage(string, time) def addInterpreterDock(self, shell): self.shellDock = QDockWidget(self) self.shellDock.setWidget(shell) self.shellDock.setWindowTitle("shell") self.addDockWidget(0x2, self.shellDock) def showMetMSInformation(self): QMessageBox.about( self, self.tr("About %1").arg("metMS"), self.tr( """<b>%1 %2</b> <br>metabolite Mass Spectrometry <p>Copyright © 2010 Marco INSA, INRA <br>Licensed under the terms of the CeciLL License <p>Developed and maintained by Marco <br>Bug reports and feature requests: <a href="http://github.com/jerkos/metms">metMS site</a><br> Discussions around the project: <a href="http://groups.google.com/group/spyderlib">Google Group</a> <p>This project is part of the BRIDGE project <p>Python %3, Qt %4, PyQt %5""" ) .arg("metMS") .arg(__version__) .arg(platform.python_version()) .arg(QT_VERSION_STR) .arg(PYQT_VERSION_STR), )
class Main(plugin.Plugin): " dock Class " def initialize(self): " Init Class dock " self.dock = QDockWidget() self.dock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.open = QAction(QIcon.fromTheme("document-open"), 'Open DIFF', self) self.diff = QAction(QIcon.fromTheme("document-new"), 'Make DIFF', self) self.diff.triggered.connect(self.run_gui_and_get_results) self.save = QAction(QIcon.fromTheme("document-save"), 'Save DIFF', self) self.save.triggered.connect(self.save_a_diff) self.patc = QAction(QIcon.fromTheme("document-edit"), 'PATCH it!', self) self.patc.triggered.connect(lambda: QMessageBox.information( self.dock, __doc__, ' Sorry. This Feature is not ready yet !, thank you... ')) QToolBar(self.dock).addActions( (self.open, self.diff, self.save, self.patc)) try: self.factory = KPluginLoader("komparepart").factory() self.part = self.factory.create(self) self.dock.setWidget(self.part.widget()) self.open.triggered.connect(lambda: self.part.openUrl( KUrl( str( QFileDialog.getOpenFileName( self.dock, ' Open a DIFF file ', path.expanduser("~"), ';;(*.diff)'))))) except: self.dock.setWidget( QLabel(""" <center> <h3>ಠ_ಠ<br> ERROR: Please, install Kompare App ! </h3><br> <br><i> (Sorry, cant embed non-Qt Apps). </i><center>""")) self.misc = self.locator.get_service('misc') self.misc.add_widget(self.dock, QIcon.fromTheme("edit-select-all"), __doc__) def run_gui_and_get_results(self): ' run_gui_and_get_results ' gui = Diff_GUI() if gui.diff_path is not None and path.isfile(gui.diff_path) is True: self.part.openUrl(KUrl(str(gui.diff_path))) return run_gui.diff_path def save_a_diff(self): ' save a diff ' out_file = path.abspath( str( QFileDialog.getSaveFileName(self.dock, 'Save a Diff file', path.expanduser("~"), ';;(*.diff)'))) inp_file = file( str(QUrl(self.part.url()).toString()).replace('file://', ''), 'r').read() end_file = file(out_file, 'w') end_file.write(inp_file) end_file.close()
class Main(plugin.Plugin): " Main Class " def initialize(self, *args, **kwargs): " Init Main Class " ec = ExplorerContainer() super(Main, self).initialize(*args, **kwargs) self.editor_s = self.locator.get_service('editor') # directory auto completer self.completer = QCompleter(self) self.dirs = QDirModel(self) self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCompletionMode(QCompleter.PopupCompletion) self.group0 = QGroupBox() self.group0.setTitle(' Source ') self.source = QComboBox() self.source.addItems(['Clipboard', 'Local File', 'Remote URL', 'Ninja']) self.source.currentIndexChanged.connect(self.on_source_changed) self.infile = QLineEdit(path.expanduser("~")) self.infile.setPlaceholderText(' /full/path/to/file.html ') self.infile.setCompleter(self.completer) self.open = QPushButton(QIcon.fromTheme("folder-open"), 'Open') self.open.setCursor(QCursor(Qt.PointingHandCursor)) self.open.clicked.connect(lambda: self.infile.setText(str( QFileDialog.getOpenFileName(self.dock, "Open a File to read from", path.expanduser("~"), ';;'.join(['{}(*.{})'.format(e.upper(), e) for e in ['css', 'html', 'js', 'txt', '*']]))))) self.inurl = QLineEdit('http://www.') self.inurl.setPlaceholderText('http://www.full/url/to/remote/file.html') self.output = QPlainTextEdit(SAMPLE_TEXT) vboxg0 = QVBoxLayout(self.group0) for each_widget in (self.source, self.infile, self.open, self.inurl, self.output, ): vboxg0.addWidget(each_widget) [a.hide() for a in iter((self.infile, self.open, self.inurl))] self.group1 = QGroupBox() self.group1.setTitle(' CSS3 ') self.group1.setCheckable(True) self.group1.setGraphicsEffect(QGraphicsBlurEffect(self)) self.group1.graphicsEffect().setEnabled(False) self.group1.toggled.connect(self.toggle_css_group) self.ckcss1 = QCheckBox('Remove unnecessary Comments') self.ckcss2 = QCheckBox('Remove unnecessary Whitespace characters') self.ckcss3 = QCheckBox('Remove unnecessary Semicolons') self.ckcss4 = QCheckBox('Remove unnecessary Empty rules') self.ckcss5 = QCheckBox('Condense and Convert Colors from RGB to HEX') self.ckcss6 = QCheckBox('Condense all Zero units') self.ckcss7 = QCheckBox('Condense Multidimensional Zero units') self.ckcss8 = QCheckBox('Condense Floating point numbers') self.ckcss9 = QCheckBox('Condense HEX Colors') self.ckcss10 = QCheckBox('Condense multiple adjacent Whitespace chars') self.ckcss11 = QCheckBox('Condense multiple adjacent semicolon chars') self.ckcss12 = QCheckBox('Wrap the lines of the to 80 character length') self.ckcss13 = QCheckBox('Condense Font Weight values') self.ckcss14 = QCheckBox('Condense the 17 Standard Named Colors values') self.ckcss15 = QCheckBox('Condense the 124 Extra Named Colors values') self.ckcss16 = QCheckBox('Condense all Percentages values when posible') self.ckcss17 = QCheckBox('Condense all Pixels values when posible') self.ckcss18 = QCheckBox('Remove unnecessary quotes from url()') self.ckcss19 = QCheckBox('Add standard Encoding Declaration if missing') vboxg1 = QVBoxLayout(self.group1) for each_widget in (self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8, self.ckcss9, self.ckcss10, self.ckcss11, self.ckcss12, self.ckcss13, self.ckcss14, self.ckcss15, self.ckcss16, self.ckcss17, self.ckcss18, self.ckcss19): vboxg1.addWidget(each_widget) each_widget.setToolTip(each_widget.text()) self.group2 = QGroupBox() self.group2.setTitle(' HTML5 ') self.group2.setCheckable(True) self.group2.setGraphicsEffect(QGraphicsBlurEffect(self)) self.group2.graphicsEffect().setEnabled(False) self.group2.toggled.connect(self.toggle_html_group) self.ckhtml0 = QCheckBox('Condense Style and Script HTML Tags') self.ckhtml1 = QCheckBox('Condense DOCTYPE to new HTML5 Tags') self.ckhtml2 = QCheckBox('Condense Href and Src to protocol agnostic') self.ckhtml4 = QCheckBox('Remove unnecessary Tags but keep HTML valid') self.help1 = QLabel('''<a href= "https://developers.google.com/speed/articles/optimizing-html"> <small><center>Help about Unneeded Unnecessary HTML tags ?</a>''') self.help1.setTextInteractionFlags(Qt.LinksAccessibleByMouse) self.help1.setOpenExternalLinks(True) vboxg2 = QVBoxLayout(self.group2) for each_widget in (self.ckhtml0, self.ckhtml1, self.ckhtml2, self.ckhtml4, self.help1, ): vboxg2.addWidget(each_widget) each_widget.setToolTip(each_widget.text()) self.group3 = QGroupBox() self.group3.setTitle(' Javascript ') self.ckjs0 = QCheckBox('Condense and Compress Javascript') self.ckjs1 = QCheckBox('Condense $(document).ready(function(){ });') vboxg2 = QVBoxLayout(self.group3) for each_widget in (self.ckjs0, self.ckjs1): vboxg2.addWidget(each_widget) each_widget.setToolTip(each_widget.text()) self.group4 = QGroupBox() self.group4.setTitle(' General ') self.chckbx1 = QCheckBox('Lower case ALL the text') self.chckbx2 = QCheckBox('Remove Spaces, Tabs, New Lines, Empty Lines') self.befor, self.after = QProgressBar(), QProgressBar() self.befor.setFormat("%v Chars") self.after.setFormat("%v Chars") vboxg4 = QVBoxLayout(self.group4) for each_widget in (self.chckbx1, self.chckbx2, QLabel('<b>Before:'), self.befor, QLabel('<b>After:'), self.after): vboxg4.addWidget(each_widget) each_widget.setToolTip(each_widget.text()) [a.setChecked(True) for a in iter((self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8, self.ckcss9, self.ckcss10, self.ckcss11, self.ckcss12, self.ckcss13, self.ckcss14, self.ckcss15, self.ckcss16, self.ckcss17, self.ckcss18, self.ckcss19, self.ckjs1, self.ckhtml0, self.ckhtml1, self.ckhtml2, self.ckhtml4, self.chckbx1, self.chckbx2))] self.button = QPushButton(QIcon.fromTheme("face-cool"), 'Process Text') self.button.setCursor(QCursor(Qt.PointingHandCursor)) self.button.setMinimumSize(100, 50) self.button.clicked.connect(self.run) def must_glow(widget_list): ' apply an glow effect to the widget ' for glow, each_widget in enumerate(widget_list): try: if each_widget.graphicsEffect() is None: glow = QGraphicsDropShadowEffect(self) glow.setOffset(0) glow.setBlurRadius(99) glow.setColor(QColor(99, 255, 255)) each_widget.setGraphicsEffect(glow) glow.setEnabled(True) except: pass must_glow((self.button, )) class TransientWidget(QWidget): ' persistant widget thingy ' def __init__(self, widget_list): ' init sub class ' super(TransientWidget, self).__init__() vbox = QVBoxLayout(self) for each_widget in widget_list: vbox.addWidget(each_widget) tw = TransientWidget((QLabel('<b>HTML5/CSS3/JS Optimizer Compressor'), self.group0, self.group1, self.group2, self.group3, self.group4, self.button, )) self.scrollable = QScrollArea() self.scrollable.setWidgetResizable(True) self.scrollable.setWidget(tw) self.dock = QDockWidget() self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.dock.setMinimumWidth(350) self.dock.setWidget(self.scrollable) ec.addTab(self.dock, "Web") QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock ).clicked.connect(lambda: QMessageBox.information(self.dock, __doc__, HELPMSG)) def run(self): ' run the string replacing ' if self.source.currentText() == 'Local File': with open(path.abspath(str(self.infile.text()).strip()), 'r') as f: txt = f.read() elif self.source.currentText() == 'Remote URL': txt = urlopen(str(self.inurl.text()).strip()).read() elif self.source.currentText() == 'Clipboard': txt = str(self.output.toPlainText()) if str(self.output.toPlainText()) is not '' else str(QApplication.clipboard().text()) else: txt = self.editor_s.get_text() self.output.clear() self.befor.setMaximum(len(txt) + 10) self.after.setMaximum(len(txt) + 10) self.befor.setValue(len(txt)) txt = txt.lower() if self.chckbx1.isChecked() is True else txt txt = condense_style(txt) if self.ckhtml0.isChecked() is True else txt txt = condense_script(txt) if self.ckhtml0.isChecked() is True else txt txt = condense_doctype(txt) if self.ckhtml1.isChecked() is True else txt txt = condense_href_src(txt) if self.ckhtml2 is True else txt txt = clean_unneeded_tags(txt) if self.ckhtml4.isChecked() is True else txt txt = condense_doc_ready(txt) if self.ckjs1.isChecked() is True else txt txt = jsmin(txt) if self.ckjs0.isChecked() is True else txt txt = remove_comments(txt) if self.ckcss1.isChecked() is True else txt txt = condense_whitespace(txt) if self.ckcss10.isChecked() is True else txt txt = remove_empty_rules(txt) if self.ckcss4.isChecked() is True else txt txt = remove_unnecessary_whitespace(txt) if self.ckcss2.isChecked() is True else txt txt = remove_unnecessary_semicolons(txt) if self.ckcss3.isChecked() is True else txt txt = condense_zero_units(txt) if self.ckcss6.isChecked() is True else txt txt = condense_multidimensional_zeros(txt) if self.ckcss7.isChecked() is True else txt txt = condense_floating_points(txt) if self.ckcss8.isChecked() is True else txt txt = normalize_rgb_colors_to_hex(txt) if self.ckcss5.isChecked() is True else txt txt = condense_hex_colors(txt) if self.ckcss9.isChecked() is True else txt txt = wrap_css_lines(txt, 80) if self.ckcss12.isChecked() is True else txt txt = condense_semicolons(txt) if self.ckcss11.isChecked() is True else txt txt = condense_font_weight(txt) if self.ckcss13.isChecked() is True else txt txt = condense_std_named_colors(txt) if self.ckcss14.isChecked() is True else txt # txt = condense_xtra_named_colors(txt) if self.ckcss14.isChecked() is True else txt # FIXME txt = condense_percentage_values(txt) if self.ckcss16.isChecked() is True else txt txt = condense_pixel_values(txt) if self.ckcss17.isChecked() is True else txt txt = remove_url_quotes(txt) if self.ckcss18.isChecked() is True else txt txt = add_encoding(txt) if self.ckcss19.isChecked() is True else txt txt = " ".join(txt.strip().split()) if self.chckbx2.isChecked() is True else txt self.after.setValue(len(txt)) self.output.setPlainText(txt) self.output.show() self.output.setFocus() self.output.selectAll() def on_source_changed(self): ' do something when the desired source has changed ' if self.source.currentText() == 'Local File': self.open.show() self.infile.show() self.inurl.hide() self.output.hide() elif self.source.currentText() == 'Remote URL': self.inurl.show() self.open.hide() self.infile.hide() self.output.hide() elif self.source.currentText() == 'Clipboard': self.output.show() self.open.hide() self.infile.hide() self.inurl.hide() self.output.setText(QApplication.clipboard().text()) else: self.output.show() self.open.hide() self.infile.hide() self.inurl.hide() self.output.setText(self.editor_s.get_text()) def toggle_css_group(self): ' toggle on or off the css checkboxes ' if self.group1.isChecked() is True: [a.setChecked(True) for a in iter((self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8, self.ckcss9, self.ckcss10, self.ckcss11, self.ckcss12, self.ckcss13, self.ckcss14, self.ckcss15, self.ckcss16, self.ckcss17, self.ckcss18, self.ckcss19))] self.group1.graphicsEffect().setEnabled(False) else: [a.setChecked(False) for a in iter((self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8, self.ckcss9, self.ckcss10, self.ckcss11, self.ckcss12, self.ckcss13, self.ckcss14, self.ckcss15, self.ckcss16, self.ckcss17, self.ckcss18, self.ckcss19))] self.group1.graphicsEffect().setEnabled(True) def toggle_html_group(self): ' toggle on or off the css checkboxes ' if self.group2.isChecked() is True: [a.setChecked(True) for a in iter((self.ckhtml0, self.ckhtml1, self.ckhtml2, self.ckhtml4))] self.group2.graphicsEffect().setEnabled(False) else: [a.setChecked(False) for a in iter((self.ckhtml0, self.ckhtml1, self.ckhtml2, self.ckhtml4))] self.group2.graphicsEffect().setEnabled(True)
class WeekliesWidget(QWidget): def __init__( self, parent = None ): super(WeekliesWidget, self).__init__( parent ) self.dockWidget = QDockWidget() parent.addDockWidget(QtCore.Qt.RightDockWidgetArea,self.dockWidget) self.dockWidget.setFloating(1) self.dockWidget.setWindowTitle("Weeklies") self.dockWidget.setWidget(self) mainlay = QtGui.QVBoxLayout() self.setLayout(mainlay) topLayout = QtGui.QHBoxLayout() mainlay.addLayout(topLayout) self.dateEdit = QtGui.QDateEdit(date.today()) self.dateEdit.setCalendarPopup(True) self.dateEdit.dateChanged.connect(self.CalculateWeeklies) topLayout.addWidget(self.dateEdit) self.textBox = QtGui.QTextEdit() self.textDocument = QtGui.QTextDocument() self.textBox.setDocument(self.textDocument) mainlay.addWidget(self.textBox) #self.setWindowFlags(QtCore.Qt.Tool) def CalculateWeeklies(self): day = self.dateEdit.date().toPyDate() #dt = datetime.strptime(day, '%d/%b/%Y') mon = day - timedelta(days=day.weekday()) fri = mon + timedelta(days=4) departmentDict = {} phaseDict = {} projList = [] text = "<b> **PROJECTS** </b>" #iterate through projects and add to project list for proj in sharedDB.myProjects.values(): if proj._startdate <= fri: if int(proj._idstatuses) < 4 or int(proj._idstatuses) == 7: projList.append(proj) projList.sort(key=operator.attrgetter('_startdate')) for proj in projList: text += "<br><u>"+proj._name+"</u> - " stat = proj._statusDescription if stat is not None and len(stat): text+=stat else: text+=sharedDB.myStatuses[str(proj._idstatuses)]._name for phase in sharedDB.myPhaseAssignments.values(): # if start before saturday and end after sunday proj = sharedDB.myProjects[str(phase._idprojects)] if phase._startdate <= fri and int(phase._idstatuses) != 5 and int(phase._idstatuses) != 6 and not 4 <= proj._idstatuses <= 6: if ((phase._enddate >= mon) and int(phase._idstatuses) != 4) or int(phase._idstatuses) != 4: departmentID = str(sharedDB.myPhases[str(phase._idphases)]._iddepartments) if departmentID in departmentDict: departmentDict[departmentID].append(phase) else: departmentDict[departmentID] = [phase] phaseID = str(phase._idphases) if phaseID in phaseDict: phaseDict[phaseID].append(phase) else: phaseDict[phaseID] = [phase] #phaselist.sort(key=operator.attrgetter('_startdate')) text += "<br><br>" for key in phaseDict.keys(): text += "<b>"+sharedDB.myPhases[key]._name+"</b>\n" phaselist = phaseDict[key] phaselist.sort(key=operator.attrgetter('_startdate')) for phase in phaselist: dateInfo = '' #starting if phase._startdate >= mon: #starting and ending this week if phase._enddate <= fri: dateInfo = "<font color=\"green\">"+phase._startdate.strftime("%m/%d")+'</font> - <font color=\"red\">'+phase._enddate.strftime("%m/%d")+'</font> - ' else: dateInfo = "<font color=\"green\">"+phase._startdate.strftime("%m/%d")+' - START</font> - ' #due elif phase._enddate <= fri: dateInfo = "<font color=\"red\">"+phase._enddate.strftime("%m/%d")+' - DUE</font> - ' #continuing else: dateInfo = 'Continuing through week... - ' #users defaultUserInfo = '<font color=\"blue\"> - UNASSIGNED</font>' userInfo = defaultUserInfo for ua in phase._userAssignments.values(): if ua._hours > 1: if userInfo == defaultUserInfo: userInfo = ' - '+sharedDB.myUsers[str(ua._idusers)]._name else: userInfo += ", "+sharedDB.myUsers[str(ua._idusers)]._name pname = sharedDB.myPhases[str(phase._idphases)]._name if pname in ["Approval","DUE","Delivery","Internal Review","Rendering"]: userInfo = "" #if phase or project on hold startTag = "<tab>" endTag = "</tab>" if phase._idstatuses == 3 or proj._idstatuses == 3: startTag += "<s>" endTag += "</s>" startTag += "**ON HOLD** " if phase._idstatuses == 4: startTag += "<s>" endTag += "</s>" if phase._description is not None and phase._description != "None": additionalInfo = " - "+phase._description else: additionalInfo = "" text += "<br>"+startTag+dateInfo+"<u>"+sharedDB.myProjects[str(phase._idprojects)]._name+"</u>"+userInfo+additionalInfo+endTag+"\n" text += "<br><br>" self.textDocument.setHtml(text)
class Main(plugin.Plugin): " Main Class " def initialize(self, *args, **kwargs): " Init Main Class " super(Main, self).initialize(*args, **kwargs) self.completer, self.dirs = QCompleter(self), QDirModel(self) self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCompletionMode(QCompleter.PopupCompletion) self.desktop, self.project, menu = '', '', QMenu('Vagrant') menu.addAction('UP', lambda: self.vagrant_c('up')) menu.addAction('HALT', lambda: self.vagrant_c('halt')) menu.addAction('RELOAD', lambda: self.vagrant_c('reload')) menu.addAction('STATUS', lambda: self.vagrant_c('status')) menu.addAction('SUSPEND', lambda: self.vagrant_c('suspend')) menu.addAction('RESUME', lambda: self.vagrant_c('resume')) menu.addAction('PROVISION', lambda: self.vagrant_c('provision')) menu.addAction('PACKAGE', lambda: self.vagrant_c('package')) menu.addAction('INIT', lambda: self.vagrant_c('init')) menu.addSeparator() menu.addAction('DESTROY (!!!)', lambda: self.vagrant_c('destroy')) self.locator.get_service('explorer').add_project_menu(menu, lang='all') self.process = QProcess() self.process.readyReadStandardOutput.connect(self.readOutput) self.process.readyReadStandardError.connect(self.readErrors) self.process.finished.connect(self._process_finished) self.process.error.connect(self._process_finished) # Proxy support, by reading http_proxy os env variable proxy_url = QUrl(environ.get('http_proxy', '')) QNetworkProxy.setApplicationProxy(QNetworkProxy(QNetworkProxy.HttpProxy if str(proxy_url.scheme()).startswith('http') else QNetworkProxy.Socks5Proxy, proxy_url.host(), proxy_url.port(), proxy_url.userName(), proxy_url.password())) \ if 'http_proxy' in environ else None self.mainwidget = QTabWidget() self.mainwidget.tabCloseRequested.connect(lambda: self.mainwidget.setTabPosition(1) if self.mainwidget.tabPosition() == 0 else self.mainwidget.setTabPosition(0)) self.mainwidget.setStyleSheet('QTabBar{font-weight:bold;}') self.mainwidget.setMovable(True) self.mainwidget.setTabsClosable(True) self.dock, self.scrollable = QDockWidget(), QScrollArea() self.scrollable.setWidgetResizable(True) self.scrollable.setWidget(self.mainwidget) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.dock.setWidget(self.scrollable) self.locator.get_service('misc').add_widget(self.dock, QIcon.fromTheme("virtualbox"), __doc__) self.tab1, self.tab2, self.tab3 = QGroupBox(), QGroupBox(), QGroupBox() self.tab4, self.tab5, self.tab6 = QGroupBox(), QGroupBox(), QGroupBox() for a, b in ((self.tab1, 'Basics'), (self.tab2, 'General Options'), (self.tab3, 'VM Package Manager'), (self.tab4, 'VM Provisioning'), (self.tab5, 'VM Desktop GUI'), (self.tab6, 'Run')): a.setTitle(b) a.setToolTip(b) self.mainwidget.addTab(a, QIcon.fromTheme("virtualbox"), b) QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock ).clicked.connect(lambda: QMessageBox.information(self.dock, __doc__, HELPMSG)) self.vmname = QLineEdit(self.get_name()) self.vmname.setPlaceholderText('type_your_VM_name_here_without_spaces') self.vmname.setToolTip('Type VM name, no spaces or special characters') self.target = QLabel('<b>Vagrant Target Folder: ' + path.join(BASE, self.vmname.text())) self.vmname.textChanged.connect(lambda: self.target.setText( '<b>Vagrant Target Folder: ' + path.join(BASE, self.vmname.text()))) self.btn1 = QPushButton(QIcon.fromTheme("face-smile-big"), 'Suggestion') self.btn1.setToolTip('Suggest me a Random VM name !') self.btn1.clicked.connect(lambda: self.vmname.setText(self.get_name())) self.vmcode, self.vmarch = QComboBox(), QComboBox() self.vmcode.addItems(['saucy', 'raring', 'quantal', 'precise']) self.vmarch.addItems(['x86_64 (amd64) 64-Bits', 'x86 (i386) 32-Bits']) vboxg1 = QVBoxLayout(self.tab1) for each_widget in (QLabel('<b>Name for VM'), self.vmname, self.btn1, QLabel('<b>Choose Ubuntu Codename for the VM:</b>'), self.vmcode, QLabel('<b>Choose Architecture for VM:'), self.vmarch, self.target): vboxg1.addWidget(each_widget) self.chrt = QCheckBox('LOW CPU priority for Backend Process') self.chttps = QComboBox() self.chttps.addItems(['https', 'http']) try: self.vinfo1 = QLabel('''<b> Vagrant Backend Version: </b> {}, <b> VirtualBox Backend Version: </b> {}. '''.format( getoutput('vagrant --version', shell=1).strip(), getoutput('vboxmanage --version', shell=1).strip())) except: self.vinfo1 = QLabel('<b>Warning: Failed to query Vagrant Backend!') self.qckb1 = QCheckBox(' Open target directory later') self.qckb1.setToolTip('Open the target directory when finished') self.qckb2 = QCheckBox(' Save a LOG file to target later') self.qckb2.setToolTip('Save a read-only .LOG file to target') self.qckb3 = QCheckBox(' NO run Headless Mode, use a Window') self.qckb3.setToolTip('Show the VM on a Window GUI instead of Headless') self.cpu, self.ram = QSpinBox(), QSpinBox() self.cpu.setRange(25, 99) self.cpu.setValue(99) self.ram.setRange(512, 4096) self.ram.setValue(1024) vboxg2 = QVBoxLayout(self.tab2) for each_widget in (self.qckb1, self.qckb2, self.qckb3, self.chrt, QLabel('<b>Max CPU Limit for VM:</b>'), self.cpu, QLabel('<b>Max RAM Limit for VM:</b>'), self.ram, QLabel('<b>Download Protocol Type:</b>'), self.chttps, self.vinfo1): vboxg2.addWidget(each_widget) self.qckb10 = QCheckBox('Run apt-get update on the created VM') self.qckb11 = QCheckBox('Run apt-get dist-upgrade on the created VM') self.qckb12 = QCheckBox('Run apt-get check on the created VM') self.qckb12 = QCheckBox('Run apt-get clean on the created VM') self.qckb13 = QCheckBox('Run apt-get autoremove on the created VM') self.qckb14 = QCheckBox('Try to Fix Broken packages if any on the VM') self.aptproxy, self.portredirect = QLineEdit(), QLineEdit('8000, 9000') self.aptproxy.setPlaceholderText(' user:password@proxyaddress:port ') vboxg3 = QVBoxLayout(self.tab3) for each_widget in (self.qckb10, self.qckb11, self.qckb12, self.qckb13, self.qckb14, QLabel('<b>Network Proxy for apt-get on the VM'), self.aptproxy, QLabel('<b>Network Port Redirects for the VM'), self.portredirect): vboxg3.addWidget(each_widget) self.aptpkg = QTextEdit('build-essential git python-pip vim mc wget') self.aptppa, self.pippkg = QLineEdit(), QTextEdit('virtualenv yolk') self.aptppa.setPlaceholderText(' ppa:ninja-ide-developers/daily ') self.requirements = QLineEdit() self.requirements.setPlaceholderText(' /full/path/to/requirements.txt ') self.requirements.setCompleter(self.completer) vboxg4 = QVBoxLayout(self.tab4) for each_widget in (QLabel('<b>Custom APT Ubuntu package'), self.aptpkg, QLabel('<b>Custom APT Ubuntu PPA:</b> '), self.aptppa, QLabel('<b>Custom PIP Python packages:</b> '), self.pippkg, QLabel('<b>Custom PIP Python requirements: '), self.requirements): vboxg4.addWidget(each_widget) self.buttonGroup = QButtonGroup() self.buttonGroup.buttonClicked[QAbstractButton].connect(self.get_de_pkg) vboxg5 = QVBoxLayout(self.tab5) for i, d in enumerate(('Ubuntu Unity', 'KDE Plasma', 'LXDE', 'XFCE')): button = QPushButton(d) button.setCheckable(True) button.setMinimumSize(75, 50) button.setToolTip(d) vboxg5.addWidget(button) self.buttonGroup.addButton(button) self.output = QTextEdit(''' We have persistent objects, they are called files. -Ken Thompson. ''') self.runbtn = QPushButton(QIcon.fromTheme("media-playback-start"), 'Start Vagrant Instrumentation Now !') self.runbtn.setMinimumSize(75, 50) self.runbtn.clicked.connect(self.build) glow = QGraphicsDropShadowEffect(self) glow.setOffset(0) glow.setBlurRadius(99) glow.setColor(QColor(99, 255, 255)) self.runbtn.setGraphicsEffect(glow) self.stopbt = QPushButton(QIcon.fromTheme("media-playback-stop"), 'Stop Vagrant') self.stopbt.clicked.connect(lambda: self.process.stop()) self.killbt = QPushButton(QIcon.fromTheme("application-exit"), 'Force Kill Vagrant') self.killbt.clicked.connect(lambda: self.process.kill()) vboxg6 = QVBoxLayout(self.tab6) for each_widget in (QLabel('<b>Multiprocess Output Logs'), self.output, self.runbtn, self.stopbt, self.killbt): vboxg6.addWidget(each_widget) [a.setChecked(True) for a in (self.qckb1, self.qckb2, self.qckb3, self.qckb10, self.qckb11, self.qckb12, self.qckb13, self.qckb14, self.chrt)] self.mainwidget.setCurrentIndex(5) def get_de_pkg(self, button): ' get package from desktop name ' if button.text() in 'Ubuntu Unity': self.desktop = 'ubuntu-desktop' elif button.text() in 'KDE Plasma': self.desktop = 'kubuntu-desktop' elif button.text() in 'LXDE': self.desktop = 'lubuntu-desktop' else: self.desktop = 'xubuntu-desktop' return self.desktop def get_name(self): ' return a random name of stars, planets and moons of solar system ' return choice((getuser(), 'sun', 'mercury', 'venus', 'earth', 'mars', 'neptun', 'ceres', 'pluto', 'haumea', 'makemake', 'eris', 'moon', 'saturn', 'europa', 'ganymede', 'callisto', 'mimas', 'enceladus', 'tethys', 'dione', 'rhea', 'titan', 'iapetus', 'miranda', 'ariel', 'umbriel', 'titania', 'oberon', 'triton', 'charon', 'orcus', 'io', 'ixion', 'varuna', 'quaoar', 'sedna', 'methone', 'jupiter', )) def readOutput(self): """Read and append output to the logBrowser""" self.output.append(str(self.process.readAllStandardOutput())) def readErrors(self): """Read and append errors to the logBrowser""" self.output.append(self.formatErrorMsg(str( self.process.readAllStandardError()))) def formatErrorMsg(self, msg): """Format error messages in red color""" return self.formatMsg(msg, 'red') def formatInfoMsg(self, msg): """Format informative messages in blue color""" return self.formatMsg(msg, 'green') def formatMsg(self, msg, color): """Format message with the given color""" return '<font color="{}">{}</font>'.format(color, msg) def build(self): """Main function calling vagrant to generate the vm""" self.output.setText('') self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now()))) self.runbtn.setDisabled(True) base = path.join(BASE, self.vmname.text()) try: self.output.append(self.formatInfoMsg('INFO: Dir: {}'.format(base))) makedirs(base) except: self.output.append(self.formatErrorMsg('ERROR:Target Folder Exist')) self.output.append(self.formatInfoMsg('INFO: Changed {}'.format(base))) chdir(base) try: self.output.append(self.formatInfoMsg('INFO:Removing Vagrant file')) remove(path.join(base, 'Vagrantfile')) except: self.output.append(self.formatErrorMsg('ERROR:Remove Vagrant file')) self.output.append(self.formatInfoMsg(' INFO: OK: Runing Vagrant Init')) cmd1 = getoutput('chrt --verbose -i 0 vagrant init', shell=True) self.output.append(self.formatInfoMsg('INFO:OK:Completed Vagrant Init')) self.output.append(self.formatInfoMsg('INFO: Command: {}'.format(cmd1))) cfg = CONFIG.format(self.vmname.text(), self.vmname.text(), self.chttps.currentText(), self.vmcode.currentText(), self.vmcode.currentText(), 'amd64' if self.vmarch.currentIndex() is 0 else 'i386', '\n'.join(([ ' config.vm.network :forwarded_port, host: {}, guest: {}'.format( a, a) for a in str(self.portredirect.text()).split(',')])), VBOXGUI.format(self.ram.value(), self.cpu.value()) if self.qckb3.isChecked() is True else '') self.output.append(self.formatInfoMsg('INFO:OK:Config: {}'.format(cfg))) with open(path.join(base, 'Vagrantfile'), 'w') as f: f.write(cfg) self.output.append(self.formatInfoMsg('INFO: Writing Vagrantfile')) f.close() proxy = APTGET_PROXY.format(self.aptproxy.text(), self.aptproxy.text(), self.aptproxy.text(), self.aptproxy.text(), self.aptproxy.text(), self.aptproxy.text()) prv = '\n'.join(('#!/usr/bin/env bash', '# -*- coding: utf-8 -*-', linesep * 2, "PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] ' ; HISTSIZE=5000", '# Vagrant Bootstrap Provisioning generated by Vagrant Ninja!', linesep, proxy if len(self.aptproxy.text()) >= 5 else '', 'add-apt-repository -s -y {}'.format(str(self.aptppa.text()).strip()), 'apt-get -V -u -m -y update' if self.qckb10.isChecked() is True else '', 'apt-get -y -m dist-upgrade' if self.qckb11.isChecked() is True else '', 'apt-get -y -m autoremove' if self.qckb11.isChecked() is True else '', 'apt-get -y clean' if self.qckb11.isChecked() is True else '', 'dpkg --configure -a' if self.qckb11.isChecked() is True else '', 'apt-get -y -f install' if self.qckb11.isChecked() is True else '', 'apt-get -y check' if self.qckb11.isChecked() is True else '', 'apt-get -y --force-yes install {}'.format(self.aptpkg.toPlainText()), 'pip install --verbose {}'.format(self.pippkg.toPlainText()), 'pip install --verbose -r {}'.format(self.requirements.text()), 'apt-get -y --force-yes -m install {}'.format(self.desktop), linesep, 'git config --global user.name "{}"'.format(getuser()), 'git config --global color.branch auto', 'git config --global color.diff auto', 'git config --global color.interactive auto', 'git config --global color.status auto', 'git config --global credential.helper cache', 'git config --global user.email "{}@gmail.com"'.format(getuser()), 'git config --global push.default simple', 'ufw status ; service ufw stop ; ufw disable ; swapoff --verbose --all', 'export LANGUAGE=en_US.UTF-8', 'export LANG=en_US.UTF-8', 'export LC_ALL=en_US.UTF-8', 'locale-gen en_US.UTF-8', 'dpkg-reconfigure locales', )) self.output.append(self.formatInfoMsg('INFO:OK:Script: {}'.format(prv))) with open(path.join(base, 'bootstrap.sh'), 'w') as f: f.write(prv) self.output.append(self.formatInfoMsg('INFO: Writing bootstrap.sh')) f.close() try: chmod('bootstrap.sh', 0775) # Py2 self.output.append(self.formatInfoMsg('INFO: bootstrap.sh is 775')) except: chmod('bootstrap.sh', 0o775) # Py3 self.output.append(self.formatInfoMsg('INFO: bootstrap.sh is o775')) self.output.append(self.formatInfoMsg(''' INFO: OK: Vagrant Up needs time, depends on your Internet Connection Speed !''')) self.output.append(self.formatInfoMsg('INFO: OK: Running Vagrant Up !')) self.process.start('{}vagrant up'.format('chrt --verbose -i 0 ' if self.chrt.isChecked() is True else '')) if not self.process.waitForStarted(): self.output.append(self.formatErrorMsg('ERROR: FAIL: Vagrant Fail')) self.runbtn.setEnabled(True) return self.runbtn.setEnabled(True) chdir(path.expanduser("~")) def _process_finished(self): """finished sucessfully""" self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now()))) if self.qckb2.isChecked() is True: LOG_FILE = path.join(BASE, self.vmname.text(), 'vagrant_ninja.log') with open(LOG_FILE, 'w') as f: self.output.append(self.formatInfoMsg('INFO: OK: Writing .LOG')) f.write(self.output.toPlainText()) f.close() if self.qckb1.isChecked() is True: self.output.append(self.formatInfoMsg('INFO:Opening Target Folder')) try: startfile(BASE) except: Popen(["xdg-open", BASE]) chdir(path.expanduser("~")) def vagrant_c(self, option): ' run the choosed menu option, kind of quick-mode ' self.output.setText('') self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now()))) self.runbtn.setDisabled(True) chdir(path.abspath( self.locator.get_service('explorer').get_current_project_item().path)) self.process.start('chrt --verbose -i 0 vagrant {}'.format(option)) if not self.process.waitForStarted(): self.output.append(self.formatErrorMsg('ERROR: FAIL: Vagrant Fail')) self.runbtn.setEnabled(True) return self.runbtn.setEnabled(True) self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now()))) chdir(path.expanduser("~")) def finish(self): ' clear when finish ' self.process.kill()
class WeekliesWidget(QWidget): def __init__(self, parent=None): super(WeekliesWidget, self).__init__(parent) self.dockWidget = QDockWidget() parent.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dockWidget) self.dockWidget.setFloating(1) self.dockWidget.setWindowTitle("Weeklies") self.dockWidget.setWidget(self) mainlay = QtGui.QVBoxLayout() self.setLayout(mainlay) topLayout = QtGui.QHBoxLayout() mainlay.addLayout(topLayout) self.dateEdit = QtGui.QDateEdit(date.today()) self.dateEdit.setCalendarPopup(True) #self.dateEdit.dateChanged.connect(self.CalculateWeeklies) self.dateEdit.dateChanged.connect(self.PopulateTable) topLayout.addWidget(self.dateEdit) self.userDropdown = QtGui.QComboBox() self.userDropdown.currentIndexChanged.connect(self.PopulateTable) topLayout.addWidget(self.userDropdown) ''' self.textBox = QtGui.QTextEdit() self.textDocument = QtGui.QTextDocument() self.textBox.setDocument(self.textDocument) ''' self.buttonPrint = QtGui.QPushButton('Print', self) self.buttonPrint.clicked.connect(self.handlePrint) self.buttonPreview = QtGui.QPushButton('Preview', self) self.buttonPreview.clicked.connect(self.handlePreview) topLayout.addWidget(self.buttonPrint) topLayout.addWidget(self.buttonPreview, 1) self.table = QtGui.QTableWidget() self.table.setColumnCount(6) self.table.verticalHeader().setVisible(False) mainlay.addWidget(self.table) ''' for i,row in enumerate(cur): self.table.insertRow(self.table.rowCount()) for j,val in enumerate(row): self.table.setItem(i, j, QtGui.QTableWidgetItem(str(val))) ''' self.PopulateUsers() #self.PopulateTable() #mainlay.addWidget(self.textBox) #sharedDB.mySQLConnection.newPhaseAssignmentSignal.connect(self.CalculateWeeklies) def PopulateUsers(self): #for user in user list userList = [] for user in sharedDB.myUsers.values(): if user.isActive() == 1: userList.extend(user.name()) self.userDropdown.addItem(user.name(), user.idUsers()) self.userDropdown.model().sort(0) def handlePrint(self): dialog = QtGui.QPrintDialog() if dialog.exec_() == QtGui.QDialog.Accepted: self.handlePaintRequest(dialog.printer()) def handlePreview(self): dialog = QtGui.QPrintPreviewDialog() dialog.paintRequested.connect(self.handlePaintRequest) dialog.exec_() def handlePaintRequest(self, printer): document = self.makeTableDocument() document.print_(printer) def makeTableDocument(self): document = QtGui.QTextDocument() cursor = QtGui.QTextCursor(document) rows = self.table.rowCount() columns = self.table.columnCount() table = cursor.insertTable(rows + 1, columns) format = table.format() format.setHeaderRowCount(1) table.setFormat(format) format = cursor.blockCharFormat() format.setFontWeight(QtGui.QFont.Bold) for column in range(columns): cursor.setCharFormat(format) cursor.insertText(self.table.horizontalHeaderItem(column).text()) cursor.movePosition(QtGui.QTextCursor.NextCell) for row in range(rows): for column in range(columns): if self.table.item(row, column) is not None: cursor.insertText(self.table.item(row, column).text()) cursor.movePosition(QtGui.QTextCursor.NextCell) return document def PopulateTable(self): day = self.dateEdit.date().toPyDate() mon = day - timedelta(days=day.weekday()) self.table.setRowCount(0) self.table.setWordWrap(1) dates = [ mon, mon + timedelta(days=1), mon + timedelta(days=2), mon + timedelta(days=3), mon + timedelta(days=4) ] self.table.setHorizontalHeaderLabels( ("", "Mon " + mon.strftime("%m/%d/%y"), "Tues " + (mon + timedelta(days=1)).strftime("%m/%d/%y"), "Wed " + (mon + timedelta(days=2)).strftime("%m/%d/%y"), "Thurs " + (mon + timedelta(days=3)).strftime("%m/%d/%y"), "Fri " + (mon + timedelta(days=4)).strftime("%m/%d/%y"))) self.table.insertRow(0) #find user then set name column currentUser = sharedDB.myUsers[str( self.userDropdown.itemData( self.userDropdown.currentIndex()).toString())] self.table.setItem(0, 0, QtGui.QTableWidgetItem(str(currentUser.name()))) #d+1 is column, b is row for d in range(0, len(dates)): #iterate through users bookings if str(dates[d]) in currentUser._bookingDict: bookings = currentUser._bookingDict[str(dates[d])] for b in range(0, len(bookings)): if b >= self.table.rowCount(): self.table.insertRow(self.table.rowCount()) #assemble Text text = sharedDB.myProjects[str(bookings[b].idprojects( ))].name() + " - " + sharedDB.myPhaseAssignments[str( bookings[b].idphaseassignments())].name() self.table.setItem(b, d + 1, QtGui.QTableWidgetItem(text)) #print bookings[b].idprojects() idphaseassignments self.table.resizeRowsToContents() '''
class CreateProjectWidget(QWidget): def __init__(self, parent=None): super(CreateProjectWidget, self).__init__(parent) # load the user interface# load the user interface if getattr(sys, 'frozen', None): #print (sys._MEIPASS+"/ui/createprojectwidget.ui"); projexui.loadUi(sys._MEIPASS, self, uifile=(sys._MEIPASS + "/ui/createprojectwidget.ui")) else: projexui.loadUi(__file__, self) #projexui.loadUi(__file__, self) # define custom properties self.dockWidget = QDockWidget() parent.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.dockWidget) self.dockWidget.setFloating(1) self.dockWidget.setWindowTitle("Create Project") self.dockWidget.setWidget(self) #self.setWindowFlags(QtCore.Qt.Tool) self._backend = None #self.myClientNameLineEdit = clientIPLineEdit.ClientIPLineEdit(self) #self.clientIPBoxLayout.addWidget(self.myClientNameLineEdit) #connects buttons self.createButton.clicked.connect(self.CreateProject) self.cancelButton.clicked.connect(self.cancel) self.UpdateClientList() self.clientComboBox.currentIndexChanged.connect(self.UpdateIPList) self.UpdateIPList(self.clientComboBox.currentIndex()) #self.open() def UpdateClientList(self): self.clientComboBox.clear() for client in sharedDB.myClients.values(): self.clientComboBox.addItem(client._name, QtCore.QVariant(client._idclients)) def UpdateIPList(self, sentclientcmboboxindex): self.ipComboBox.clear() #print sharedDB.myClients[str(self.clientComboBox.itemData(self.clientComboBox.currentIndex()).toString())] if str( self.clientComboBox.itemData(self.clientComboBox.currentIndex( )).toString()) in sharedDB.myClients: client = sharedDB.myClients[str( self.clientComboBox.itemData( self.clientComboBox.currentIndex()).toString())] #if str(client._idclients) == self.clientComboBox.itemData(sentclientid).toString(): for ip in client._ips.values(): self.ipComboBox.addItem(ip._name, QtCore.QVariant(ip._idips)) def cancel(self): self.close() def setDefaults(self): #set initial values self.duedateEdit.setDate(QDate.currentDate().addDays(30)) self.xres_spinBox.setValue(1280) self.yres_spinBox.setValue(720) self.phaseListWidget.clear() for myPhase in sharedDB.myPhases.values(): if myPhase._name != "DUE": item = QtGui.QListWidgetItem(myPhase._name) self.phaseListWidget.addItem(item) self.phaseListWidget.setItemSelected(item, True) self.descriptionTextEdit.setText("") self.durationEdit.setTime(QTime.fromString("00:01:00")) self.projectNameQLineEdit.setText("Project Name") self.fps.setValue(25) '''def open(self): self.show() self.activateWindow() ''' def CreateProject(self): name = str(self.projectNameQLineEdit.text()) folderLocation = '' #idstatus = 0 idips = str( self.ipComboBox.itemData( self.ipComboBox.currentIndex()).toString()) idclients = str( self.clientComboBox.itemData( self.clientComboBox.currentIndex()).toString()) fps = self.fps.value() renderWidth = self.xres_spinBox.value() renderHeight = self.yres_spinBox.value() due_date = self.duedateEdit.date().toPyDate() renderPriority = 50 description = self.descriptionTextEdit.toPlainText() phases = [] #for each list item for item in self.phaseListWidget.selectedItems(): #get phase of same name for x in range(0, len(sharedDB.myPhases))[::-1]: #print sharedDB.myPhases[x]._name #print item.text if sharedDB.myPhases.values()[x]._name == item.text(): phases.append( sharedDB.phaseAssignments.PhaseAssignments( _idphases=sharedDB.myPhases.values()[x].id(), _startdate=due_date, _enddate=due_date, _updated=0)) continue #start from due date and work backwards #for phases = InitializeDates(phases, due_date, self.durationEdit.time()) #Add due date into phases phases.append( sharedDB.phaseAssignments.PhaseAssignments(_idphases=16, _startdate=due_date, _enddate=due_date, _updated=0)) newProj = sharedDB.projects.Projects(_name=name, _folderLocation='', _idstatuses=1, _fps=fps, _renderWidth=renderWidth, _renderHeight=renderHeight, _due_date=due_date, _renderPriority=renderPriority, _description=description, _idips=idips, _idclients=idclients, _new=0) newProj._new = 1 newProj.Save() #sharedDB.myProjects.append(newProj) #connect phases to projectid for phase in phases: newProj.AddPhase(phase) ''' phase._idprojects = newProj._idprojects phase.project = newProj phase._new = 1 phase.Save() newProj._phases[str(phase.id())] = phase ''' if str(idips) in sharedDB.myIps: ip = sharedDB.myIps[str(idips)] ip._projects[str(newProj.id())] = newProj newProj.UpdateStartDate() self.close()
class CreateProjectWidget(QWidget): def __init__( self, parent = None ): super(CreateProjectWidget, self).__init__( parent ) # load the user interface# load the user interface if getattr(sys, 'frozen', None): #print (sys._MEIPASS+"/ui/createprojectwidget.ui"); projexui.loadUi(sys._MEIPASS, self, uifile = (sys._MEIPASS+"/ui/createprojectwidget.ui")) else: projexui.loadUi(__file__, self) #projexui.loadUi(__file__, self) # define custom properties self.dockWidget = QDockWidget() parent.addDockWidget(QtCore.Qt.LeftDockWidgetArea,self.dockWidget) self.dockWidget.setFloating(1) self.dockWidget.setWindowTitle("Create Project") self.dockWidget.setWidget(self) #self.setWindowFlags(QtCore.Qt.Tool) self._backend = None #self.myClientNameLineEdit = clientIPLineEdit.ClientIPLineEdit(self) #self.clientIPBoxLayout.addWidget(self.myClientNameLineEdit) #connects buttons self.createButton.clicked.connect(self.CreateProject) self.cancelButton.clicked.connect(self.cancel) self.UpdateClientList() self.clientComboBox.currentIndexChanged.connect(self.UpdateIPList) self.UpdateIPList(self.clientComboBox.currentIndex()) #self.open() def UpdateClientList(self): self.clientComboBox.clear() for client in sharedDB.myClients.values(): self.clientComboBox.addItem(client._name,QtCore.QVariant(client._idclients)) def UpdateIPList(self, sentclientcmboboxindex): self.ipComboBox.clear() #print sharedDB.myClients[str(self.clientComboBox.itemData(self.clientComboBox.currentIndex()).toString())] if str(self.clientComboBox.itemData(self.clientComboBox.currentIndex()).toString()) in sharedDB.myClients: client = sharedDB.myClients[str(self.clientComboBox.itemData(self.clientComboBox.currentIndex()).toString())] #if str(client._idclients) == self.clientComboBox.itemData(sentclientid).toString(): for ip in client._ips.values(): self.ipComboBox.addItem(ip._name,QtCore.QVariant(ip._idips)) def cancel(self): self.close() def setDefaults(self): #set initial values self.duedateEdit.setDate(QDate.currentDate().addDays(30)) self.xres_spinBox.setValue(1280) self.yres_spinBox.setValue(720) self.phaseListWidget.clear() for myPhase in sharedDB.myPhases.values(): if myPhase._name != "DUE": item = QtGui.QListWidgetItem(myPhase._name) self.phaseListWidget.addItem(item) self.phaseListWidget.setItemSelected(item,True) self.descriptionTextEdit.setText("") self.durationEdit.setTime(QTime.fromString("00:01:00")) self.projectNameQLineEdit.setText("Project Name") self.fps.setValue(25) '''def open(self): self.show() self.activateWindow() ''' def CreateProject(self): name = str(self.projectNameQLineEdit.text()) folderLocation = '' #idstatus = 0 idips = str(self.ipComboBox.itemData(self.ipComboBox.currentIndex()).toString()) idclients = str(self.clientComboBox.itemData(self.clientComboBox.currentIndex()).toString()) fps = self.fps.value() renderWidth = self.xres_spinBox.value() renderHeight = self.yres_spinBox.value() due_date = self.duedateEdit.date().toPyDate(); renderPriority = 50 description = self.descriptionTextEdit.toPlainText() phases = [] #for each list item for item in self.phaseListWidget.selectedItems(): #get phase of same name for x in range(0,len(sharedDB.myPhases))[::-1]: #print sharedDB.myPhases[x]._name #print item.text if sharedDB.myPhases.values()[x]._name == item.text(): phases.append(sharedDB.phaseAssignments.PhaseAssignments(_idphases = sharedDB.myPhases.values()[x].id(), _startdate = due_date,_enddate = due_date,_updated = 0)) continue #start from due date and work backwards #for phases = InitializeDates(phases,due_date,self.durationEdit.time()) #Add due date into phases phases.append(sharedDB.phaseAssignments.PhaseAssignments(_idphases = 16, _startdate = due_date,_enddate = due_date,_updated = 0)) newProj = sharedDB.projects.Projects(_name = name, _folderLocation = '', _idstatuses = 1, _fps = fps, _renderWidth = renderWidth, _renderHeight = renderHeight, _due_date = due_date, _renderPriority = renderPriority, _description = description, _idips = idips, _idclients = idclients, _new = 0) newProj._new = 1 newProj.Save() #sharedDB.myProjects.append(newProj) #connect phases to projectid for phase in phases: newProj.AddPhase(phase) ''' phase._idprojects = newProj._idprojects phase.project = newProj phase._new = 1 phase.Save() newProj._phases[str(phase.id())] = phase ''' if str(idips) in sharedDB.myIps: ip = sharedDB.myIps[str(idips)] ip._projects[str(newProj.id())] = newProj self.close();
class GUI(QMainWindow): def __init__(self, debug=False): QMainWindow.__init__(self) # initialise filename self.filename = None # make the data store from xmlstore import Store self.store = Store(debug = debug) # view the current table self.tableView = TableView(self) self.tableView.setDragEnabled(True); self.tableView.setAcceptDrops(True); self.tableView.setDropIndicatorShown(True); self.setCentralWidget(self.tableView) # add a custom delegate to it self.delegate = ComboBoxDelegate() self.tableView.setItemDelegate(self.delegate) # dock the table selection on the left self.dock1 = QDockWidget(self) self.listView = ListView(self) self.listView.setDragEnabled(True); self.listView.setDragDropMode(QAbstractItemView.InternalMove) self.listView.setDropIndicatorShown(True); self.dock1.setWidget(self.listView) self.dock1.setFeatures( QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.addDockWidget(Qt.LeftDockWidgetArea, self.dock1) # connect it to the populate method self.connect(self.listView, SIGNAL('activated ( const QModelIndex & )'), self.populate) self.connect(self.listView, SIGNAL('clicked ( const QModelIndex & )'), self.populate) # dock the undoView on the left self.dock2 = QDockWidget(self) self.undoView = QUndoView(self.store.stack) self.dock2.setWidget(self.undoView) self.dock2.setFeatures( QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock2.setWindowTitle('Undo Stack') self.addDockWidget(Qt.LeftDockWidgetArea, self.dock2) # create a menubar self.menu = self.menuBar() # create file menu headings self.menuFile = self.menu.addMenu('File') self.menuFile.addAction('New', self.New).setShortcut('CTRL+N') self.menuFile.addAction('Open...', self.Open).setShortcut('CTRL+O') self.menuFile.addAction('Reload', self.Reload) self.menuFile.addAction('Save', self.Save).setShortcut('CTRL+S') self.menuFile.addAction('Save As...', self.SaveAs) self.menuFile.addSeparator() self.menuFile.addAction('Set Architecture...', self.setArch) self.menuFile.addSeparator() self.menuFile.addAction('Quit', self.closeEvent).setShortcuts(['CTRL+Q', 'ALT+F4']) # create edit menu headings self.menuEdit = self.menu.addMenu('Edit') self.menuEdit.addAction('Insert Row', self.tableView.insertRow).setShortcut('CTRL+I') self.menuEdit.addAction('Insert Row Under', self.tableView.insertRowUnder).setShortcut('CTRL+U') self.menuEdit.addAction('Remove Row', self.tableView.removeRow) self.menuEdit.addSeparator() self.menuEdit.addAction('Cut', self.tableView.cut).setShortcut('CTRL+X') self.menuEdit.addAction('Copy', self.tableView.copy).setShortcuts(['CTRL+C', 'CTRL+INS']) self.menuEdit.addAction('Paste', self.tableView.paste).setShortcuts(['CTRL+V', 'SHIFT+INS']) self.menuEdit.addAction('Clear', self.tableView.menuClear).setShortcut('CTRL+D') self.menuEdit.addSeparator() self.menuEdit.addAction('Fill Cells', self.tableView.fillCells).setShortcut('CTRL+L') self.menuEdit.addAction('Fill Cells and Increment', self.tableView.fillCellsInc).setShortcut('CTRL+R') self.menuEdit.addAction('Python Code...', self.tableView.pythonCode).setShortcut('CTRL+P') self.tableView.codeBox = pythonCode() self.menuEdit.addSeparator() self.menuEdit.addAction('Undo', self.store.stack, SLOT('undo()')).setShortcut('CTRL+Z') self.menuEdit.addAction('Redo', self.store.stack, SLOT('redo()')).setShortcut('CTRL+SHIFT+Z') # create component menu self.menuComponents = self.menu.addMenu('Components') self.resize(QSize(1000,500)) def Save(self): # save menu command self.SaveAs(self.filename) def setArch(self): arch = self.store.getArch() arch, ok = QInputDialog.getText(self, 'Architecture Dialog', 'Enter Architecture', QLineEdit.Normal, arch) arch = str(arch) if ok: self.store.setArch(arch) def SaveAs(self, filename = ''): # save as menu command if filename == '': filename = str(QFileDialog.getSaveFileName()) if filename != '': self.filename = filename self.store.Save(filename) self._setClean() def Reload(self): if self.filename is not None: self.Open(self.filename, name = self.tablename) def Open(self, filename = '', name = None): # make sure the user is sure if there are unsaved changes if self.__prompt_unsaved() != QMessageBox.Yes: return # ask for a filename if filename == '': filename = str(QFileDialog.getOpenFileName()) if filename == '': return # store the filename self.filename = filename # tell the store to open a new set of tables try: problems, warnings = self.store.Open(filename) if problems: errorstr = 'Can\'t load all object types: '+', '.join(problems) QMessageBox.warning(self,'Open Error',errorstr) if warnings: errorstr = \ 'The following warnings were generated:\n' + \ '\n'.join(warnings) QMessageBox.warning(self,'Open Warnings',errorstr) except Exception, e: x = formLog('An error ocurred. Make sure all the modules listed ' 'in RELEASE files are built. Check the text below for ' 'details:\n\n' + traceback.format_exc(), self) x.show() return # populate self.setWindowTitle('XEB - %s[*]'%filename) self.listView.clear() for t in self.store.getTableNames(): self.__insertListViewItem(t) self.__populateMenu() self.populate(name = name) self._setClean()
class MainWindow(QMainWindow, Ui_MainWindow): """The Main window of Luma. """ logger = logging.getLogger(__name__) languages = {} translator = None languageHandler = None currentLanguage = '' def __init__(self, parent=None): """The constructor sets up the MainWindow widget, and connects all necessary signals and slots """ super(MainWindow, self).__init__(parent) self.setupUi(self) # We store the window size to make sure the previous window size # is restored when leaving fullscreen mode. This varible is used # in the toggleFullscreen slot. self.__tmpWinSize = self.size() self.eventFilter = LumaEventFilter(self) self.mainTabs.installEventFilter(self.eventFilter) self.translator = QTranslator() self.languageHandler = LanguageHandler() self.languages = self.languageHandler.availableLanguages #self.__createPluginToolBar() self.__createLoggerWidget() self.__loadSettings() self.__createLanguageOptions() self.setStatusBar(self.statusBar) self.mainTabs.setTabsClosable(True) self.mainTabs.setContextMenuPolicy(Qt.CustomContextMenu) self.mainTabs.customContextMenuRequested.connect( self.__mainTabsContextMenu) self.defaultTabStyle = '' self.lumaHeadStyle = 'background: url(:/icons/luma-gray);\n' + \ 'background-position: bottom right;\n' + \ 'background-attachment: fixed;\n' + \ 'background-repeat: no-repeat;' #Sets up pluginWidget #self in parameter is used to call pluginSelected here... self.pluginWidget = PluginListWidget(self) self.showPlugins() self.welcomeTab = WelcomeTab() self.welcomeTab.textBrowser.setStyleSheet(self.lumaHeadStyle) #This value comes from __loadSettings() #Its a checkbox set in WelcomeTab if self.showWelcomeSettings == 2: self.showWelcome() else: # Let's do some styling of the tab widget when no tabs are opened if self.mainTabs.currentIndex() == -1: self.__setTabWidgetStyle(self.lumaHeadStyle) self.actionShowWelcomeTab.setEnabled(True) self.serversChangedMessage = QErrorMessage(self) def __mainTabsContextMenu(self, pos): menu = QMenu() if self.mainTabs.count() > 0: return # The menu is displayed even when the rightclick is not # done over the actual tabs so to avoid confusion the # function is disabled entirey #menu.addAction(QApplication.translate( # "MainWindow", "Close all plugin-tabs"), self.tabCloseAll) else: # If there's no tabs, offer to display the pluginlist menu.addAction(self.actionShowPluginList) menu.exec_(self.mainTabs.mapToGlobal(pos)) def __createPluginToolBar(self): """Creates the pluign toolbar. """ self.pluginToolBar = PluginToolBar(self) self.pluginToolBar.setWindowTitle(QApplication.translate( 'MainWindow', 'Plugintoolbar', None, QApplication.UnicodeUTF8)) self.pluginToolBar.setObjectName('pluginToolBar') self.addToolBar(self.pluginToolBar) self.pluginToolBar.hide() def __createLoggerWidget(self): """Creates the logger widget. """ self.loggerDockWindow = QDockWidget(self) self.loggerDockWindow.setObjectName('loggerDockWindow') self.loggerDockWindow.visibilityChanged[bool].connect( self.actionShowLogger.setChecked) self.loggerDockWindow.setWindowTitle(QApplication.translate( 'MainWindow', 'Logger', None, QApplication.UnicodeUTF8)) self.loggerWidget = LoggerWidget(self.loggerDockWindow) self.loggerDockWindow.setWidget(self.loggerWidget) self.addDockWidget(Qt.BottomDockWidgetArea, self.loggerDockWindow) self.loggerDockWindow.hide() def __createLanguageOptions(self): """Creates the language selection in the menubar. """ self.langGroup = QActionGroup(self) self.langGroup.setExclusive(True) self.langGroup.triggered['QAction*'].connect(self.languageChanged) for key, name in self.languages.iteritems(): action = QAction(self) action.setCheckable(True) action.setData(key) action.setText(name[0]) action.setStatusTip(name[1]) action.setActionGroup(self.langGroup) self.menuLanguage.addAction(action) if key == self.currentLanguage: action.setChecked(True) def __loadSettings(self, mainWin=True): """Loads settings from file. :param mainWin: If set to ``False``, neither the values for the window size or the window position will be loaded. This is i.e done when the settings dialog returns 1. :type mainWin: bool """ settings = Settings() # We might want to use these methods to restore the # application state and geometry. if mainWin: self.restoreGeometry(settings.geometry) #self.restoreState(settings.state) # If the geometry saved inticates fullscreen mode, # we need to explicitly set the fullscreen menuaction checkbox if self.isFullScreen(): self.actionFullscreen.setChecked(True) # Logger # Logger # The `allwaysShowLoggerOnStart` a precedence on the # `showLogger` value. if settings.showLoggerOnStart: self.actionShowLogger.setChecked(True) else: self.actionShowLogger.setChecked(settings.showLogger) self.loggerWidget.errorBox.setChecked(settings.showErrors) self.loggerWidget.debugBox.setChecked(settings.showDebug) self.loggerWidget.infoBox.setChecked(settings.showInfo) self.toggleLoggerWindow(self.actionShowLogger.isChecked()) # Language self.loadLanguage(settings.language) #Tabs self.showWelcomeSettings = settings.value("showWelcome", 2).toInt()[0] def __writeSettings(self): """Save settings to file. """ settings = Settings() # We might want to use these methods to restore the # application state and geometry. settings.geometry = self.saveGeometry() #settings.state = self.saveState() # Mainwin #max = self.isMaximized() #settings.maximize = max #if not max: # settings.size = self.size() # settings.position = self.pos() # The global logger settings is managed from the settings dialog. # Logger settings.showLogger = self.actionShowLogger.isChecked() settings.showErrors = self.loggerWidget.errorBox.isChecked() settings.showDebug = self.loggerWidget.debugBox.isChecked() settings.showInfo = self.loggerWidget.infoBox.isChecked() # Language settings.language = self.currentLanguage def __switchTranslator(self, translator, qmFile): """Called when a new language is loaded. :param translator: The translator object to install. :type translator: QTranslator :qmFile: The translation file for the loaded language. :type qmFile: string """ qApp.removeTranslator(translator) if translator.load(qmFile): qApp.installTranslator(translator) def __setTabWidgetStyle(self, stylesheet): self.mainTabs.setStyleSheet(stylesheet) @pyqtSlot('QAction*') @pyqtSlot(int) def languageChanged(self, value): """This slot is called by actions and signals related to application translations. The slot contains validation for those parameters defined by the pyqtSlot meta info in the method header. :param value: Can be either a ``QAction`` or an integer value. I.e. menu actions provide ``QActions`` but a ``QCombobox`` might send it's index. :type value: QAction/int """ locale = None if isinstance(value, int): locale = self.languageSelector.itemData(value).toString() elif isinstance(value, QAction): locale = value.data().toString() #else: # locale = value if locale: self.loadLanguage(locale) def loadLanguage(self, locale): """Loads a language by the given language iso code. :param locale: A twoletter lowercase ISO 639 language code and possibly a twoletter uppercase ISO 3166 country code separeted by a underscore. :type locale: string """ if self.currentLanguage != locale: self.currentLanguage = locale qmFile = self.languageHandler.getQmFile(locale) self.__switchTranslator(self.translator, qmFile) def changeEvent(self, event): """This event is called when a new translator is loaded or the system language (locale) is changed. :param event: The event that generated the `changeEvent`. :type event: QEvent """ if None != event: type = event.type() if QEvent.LanguageChange == type or QEvent.LocaleChange == type: self.retranslateUi(self) self.loggerWidget.retranslateUi(self.loggerWidget) def showAboutLuma(self): """Slot for displaying the about dialog. """ AboutDialog().exec_() @pyqtSlot(bool) def toggleLoggerWindow(self, show): """Slot for toggling the logger window. :param show: a boolean value indicating whether the logger window should be shown or not. :type show: bool """ if show: self.loggerDockWindow.show() else: self.loggerDockWindow.hide() @pyqtSlot(bool) def toggleStatusbar(self, show): """Slot for toggling the logger window. :param show: a boolean value indicating whether the statusbar should be shown or not. :type show: bool """ if show: self.statusBar.show() else: self.statusBar.hide() @pyqtSlot(bool) def toggleFullscreen(self, fullscreen): """Slot for toggling the logger window. :param fullscreen: a boolean value indicating whether to enter fullscreenmode or not. :type fullcreen: bool """ if fullscreen: self.__tmpWinSize = self.size() self.showFullScreen() else: self.showNormal() self.resize(self.__tmpWinSize) def showServerEditor(self): """Slot to display the server editor dialog. """ serverEditor = ServerDialog() r = serverEditor.exec_() if r: #TODO -- only display if plugins open: self.serversChangedMessage.showMessage(QApplication.translate( "MainWindow", "You may need to restart plugins for changes to take effect.")) def showTempPasswordDialog(self): """ Sets overridePassword for a server. Using this one doesn't actually have to enter the password in the ServerDialog (and by extension save to disk). """ serverList = ServerList() # Create a stringlist to be used by the qinputdialog stringList = [] for server in serverList.getTable(): stringList.append(server.name) # Display list of servers (serverString, ok) = QInputDialog.getItem( self, QApplication.translate("MainWindow", "Select server"), QApplication.translate("MainWindow", "Server:"), stringList, editable=False ) if ok: server = serverList.getServerObjectByName(serverString) if server != None: # Ask for password (value, ok) = QInputDialog.getText( self, QApplication.translate("MainWindow", "Temporary password"), QApplication.translate("MainWindow", "Enter password:"******"""Slot to display the settings dialog. If the settings dialog returns 1, i.e. the user has clicked the ok button, the loadSettings method is called with mainWin=False, to load the (assumed) newly changed settings. :param tab: The index of the tab to display in the settings dialog. :type tab: int """ #settingsDialog = SettingsDialog(self.currentLanguage, self.languages) settingsDialog = SettingsDialog() if tab < 0: tab = 0 settingsDialog.tabWidget.setCurrentIndex(tab) if settingsDialog.exec_(): self.reloadPlugins() # # We assume that some settings is changed # # if the user clicked the ok button, and # # reloads the application settings # self.__loadSettings(mainWin=False) # # A Hack but it'll do for now # for a in self.langGroup.actions(): # if a.data().toString() == self.currentLanguage: # a.setChecked(True) def configurePlugins(self): """Slot to display the plugins configuration. This currently calls `showSettingsDialog` with tab index set to 2. """ self.showSettingsDialog(1) def reloadPlugins(self): """Slot to reload plugins. """ self.pluginWidget.updatePlugins() def pluginSelected(self, item): """This method will be called from the `PluginListWidget`. """ # Clear the stylesheet when a tab is opened self.__setTabWidgetStyle(self.defaultTabStyle) widget = item.plugin.getPluginWidget(None, self) if platform.system() == "Windows": scroll = QScrollArea() scroll.setWidget(widget) scroll.setWidgetResizable(True) index = self.mainTabs.addTab( scroll, item.icon(), item.plugin.pluginUserString) else: index = self.mainTabs.addTab( widget, item.icon(), item.plugin.pluginUserString) self.mainTabs.setCurrentIndex(index) def tabClose(self, index): """Slot for the signal `tabCloseRequest(int)` for the tabMains. """ widget = self.mainTabs.widget(index) # If the tab closed is one of these, enable the toggle-action if widget == self.pluginWidget: self.actionShowPluginList.setEnabled(True) if widget == self.welcomeTab: self.actionShowWelcomeTab.setEnabled(True) self.mainTabs.removeTab(index) # Unparent the widget since it was reparented by the QTabWidget # so it's garbage collected widget.setParent(None) # In case the widget contained circular references # -- force GC to take care of the objects since there can be # quite many if it was BrowserWidget that was closed. # Can't call it directly since that'll be too soon QTimer.singleShot(1000, self.gc) # Let's do some styling of the tab widget when no tabs are opened if self.mainTabs.currentIndex() == -1: self.__setTabWidgetStyle(self.lumaHeadStyle) def gc(self): """Runs Python's garbage-collection manually. Used to make sure circular references are taken care of *now*. """ gc.collect() def showWelcome(self): """Shows the Welcome-tab """ self.__setTabWidgetStyle(self.defaultTabStyle) index = self.mainTabs.addTab(self.welcomeTab, QApplication.translate("MainWindow", "Welcome")) self.mainTabs.setCurrentIndex(index) self.actionShowWelcomeTab.setEnabled(False) def showPlugins(self): """Will show the pluginlistwidget-tab """ self.__setTabWidgetStyle(self.defaultTabStyle) if self.mainTabs.indexOf(self.pluginWidget) == -1: index = self.mainTabs.addTab( self.pluginWidget, QApplication.translate( "MainWindow", "Plugins")) self.mainTabs.setCurrentIndex(index) self.actionShowPluginList.setEnabled(False) def closeEvent(self, e): """Overrides the ``QMainWindow.closeEvent`` slot to save settings before we tear down the application. """ self.__writeSettings() QMainWindow.closeEvent(self, e)
class MainWindow(QMainWindow, Ui_MainWindow): """The Main window of Luma. """ logger = logging.getLogger(__name__) languages = {} translator = None languageHandler = None currentLanguage = '' def __init__(self, parent=None): """The constructor sets up the MainWindow widget, and connects all necessary signals and slots """ super(MainWindow, self).__init__(parent) self.setupUi(self) # We store the window size to make sure the previous window size # is restored when leaving fullscreen mode. This varible is used # in the toggleFullscreen slot. self.__tmpWinSize = self.size() self.eventFilter = LumaEventFilter(self) self.mainTabs.installEventFilter(self.eventFilter) self.translator = QTranslator() self.languageHandler = LanguageHandler() self.languages = self.languageHandler.availableLanguages #self.__createPluginToolBar() self.__createLoggerWidget() self.__loadSettings() self.__createLanguageOptions() self.setStatusBar(self.statusBar) self.mainTabs.setTabsClosable(True) self.mainTabs.setContextMenuPolicy(Qt.CustomContextMenu) self.mainTabs.customContextMenuRequested.connect( self.__mainTabsContextMenu) self.defaultTabStyle = '' self.lumaHeadStyle = 'background: url(:/icons/luma-gray);\n' + \ 'background-position: bottom right;\n' + \ 'background-attachment: fixed;\n' + \ 'background-repeat: no-repeat;' #Sets up pluginWidget #self in parameter is used to call pluginSelected here... self.pluginWidget = PluginListWidget(self) self.showPlugins() self.welcomeTab = WelcomeTab() self.welcomeTab.textBrowser.setStyleSheet(self.lumaHeadStyle) #This value comes from __loadSettings() #Its a checkbox set in WelcomeTab if self.showWelcomeSettings == 2: self.showWelcome() else: # Let's do some styling of the tab widget when no tabs are opened if self.mainTabs.currentIndex() == -1: self.__setTabWidgetStyle(self.lumaHeadStyle) self.actionShowWelcomeTab.setEnabled(True) self.serversChangedMessage = QErrorMessage(self) def __mainTabsContextMenu(self, pos): menu = QMenu() if self.mainTabs.count() > 0: return # The menu is displayed even when the rightclick is not # done over the actual tabs so to avoid confusion the # function is disabled entirey #menu.addAction(QApplication.translate( # "MainWindow", "Close all plugin-tabs"), self.tabCloseAll) else: # If there's no tabs, offer to display the pluginlist menu.addAction(self.actionShowPluginList) menu.exec_(self.mainTabs.mapToGlobal(pos)) def __createPluginToolBar(self): """Creates the pluign toolbar. """ self.pluginToolBar = PluginToolBar(self) self.pluginToolBar.setWindowTitle( QApplication.translate('MainWindow', 'Plugintoolbar', None, QApplication.UnicodeUTF8)) self.pluginToolBar.setObjectName('pluginToolBar') self.addToolBar(self.pluginToolBar) self.pluginToolBar.hide() def __createLoggerWidget(self): """Creates the logger widget. """ self.loggerDockWindow = QDockWidget(self) self.loggerDockWindow.setObjectName('loggerDockWindow') self.loggerDockWindow.visibilityChanged[bool].connect( self.actionShowLogger.setChecked) self.loggerDockWindow.setWindowTitle( QApplication.translate('MainWindow', 'Logger', None, QApplication.UnicodeUTF8)) self.loggerWidget = LoggerWidget(self.loggerDockWindow) self.loggerDockWindow.setWidget(self.loggerWidget) self.addDockWidget(Qt.BottomDockWidgetArea, self.loggerDockWindow) self.loggerDockWindow.hide() def __createLanguageOptions(self): """Creates the language selection in the menubar. """ self.langGroup = QActionGroup(self) self.langGroup.setExclusive(True) self.langGroup.triggered['QAction*'].connect(self.languageChanged) for key, name in self.languages.iteritems(): action = QAction(self) action.setCheckable(True) action.setData(key) action.setText(name[0]) action.setStatusTip(name[1]) action.setActionGroup(self.langGroup) self.menuLanguage.addAction(action) if key == self.currentLanguage: action.setChecked(True) def __loadSettings(self, mainWin=True): """Loads settings from file. :param mainWin: If set to ``False``, neither the values for the window size or the window position will be loaded. This is i.e done when the settings dialog returns 1. :type mainWin: bool """ settings = Settings() # We might want to use these methods to restore the # application state and geometry. if mainWin: self.restoreGeometry(settings.geometry) #self.restoreState(settings.state) # If the geometry saved inticates fullscreen mode, # we need to explicitly set the fullscreen menuaction checkbox if self.isFullScreen(): self.actionFullscreen.setChecked(True) # Logger # Logger # The `allwaysShowLoggerOnStart` a precedence on the # `showLogger` value. if settings.showLoggerOnStart: self.actionShowLogger.setChecked(True) else: self.actionShowLogger.setChecked(settings.showLogger) self.loggerWidget.errorBox.setChecked(settings.showErrors) self.loggerWidget.debugBox.setChecked(settings.showDebug) self.loggerWidget.infoBox.setChecked(settings.showInfo) self.toggleLoggerWindow(self.actionShowLogger.isChecked()) # Language self.loadLanguage(settings.language) #Tabs self.showWelcomeSettings = settings.value("showWelcome", 2).toInt()[0] def __writeSettings(self): """Save settings to file. """ settings = Settings() # We might want to use these methods to restore the # application state and geometry. settings.geometry = self.saveGeometry() #settings.state = self.saveState() # Mainwin #max = self.isMaximized() #settings.maximize = max #if not max: # settings.size = self.size() # settings.position = self.pos() # The global logger settings is managed from the settings dialog. # Logger settings.showLogger = self.actionShowLogger.isChecked() settings.showErrors = self.loggerWidget.errorBox.isChecked() settings.showDebug = self.loggerWidget.debugBox.isChecked() settings.showInfo = self.loggerWidget.infoBox.isChecked() # Language settings.language = self.currentLanguage def __switchTranslator(self, translator, qmFile): """Called when a new language is loaded. :param translator: The translator object to install. :type translator: QTranslator :qmFile: The translation file for the loaded language. :type qmFile: string """ qApp.removeTranslator(translator) if translator.load(qmFile): qApp.installTranslator(translator) def __setTabWidgetStyle(self, stylesheet): self.mainTabs.setStyleSheet(stylesheet) @pyqtSlot('QAction*') @pyqtSlot(int) def languageChanged(self, value): """This slot is called by actions and signals related to application translations. The slot contains validation for those parameters defined by the pyqtSlot meta info in the method header. :param value: Can be either a ``QAction`` or an integer value. I.e. menu actions provide ``QActions`` but a ``QCombobox`` might send it's index. :type value: QAction/int """ locale = None if isinstance(value, int): locale = self.languageSelector.itemData(value).toString() elif isinstance(value, QAction): locale = value.data().toString() #else: # locale = value if locale: self.loadLanguage(locale) def loadLanguage(self, locale): """Loads a language by the given language iso code. :param locale: A twoletter lowercase ISO 639 language code and possibly a twoletter uppercase ISO 3166 country code separeted by a underscore. :type locale: string """ if self.currentLanguage != locale: self.currentLanguage = locale qmFile = self.languageHandler.getQmFile(locale) self.__switchTranslator(self.translator, qmFile) def changeEvent(self, event): """This event is called when a new translator is loaded or the system language (locale) is changed. :param event: The event that generated the `changeEvent`. :type event: QEvent """ if None != event: type = event.type() if QEvent.LanguageChange == type or QEvent.LocaleChange == type: self.retranslateUi(self) self.loggerWidget.retranslateUi(self.loggerWidget) def showAboutLuma(self): """Slot for displaying the about dialog. """ AboutDialog().exec_() @pyqtSlot(bool) def toggleLoggerWindow(self, show): """Slot for toggling the logger window. :param show: a boolean value indicating whether the logger window should be shown or not. :type show: bool """ if show: self.loggerDockWindow.show() else: self.loggerDockWindow.hide() @pyqtSlot(bool) def toggleStatusbar(self, show): """Slot for toggling the logger window. :param show: a boolean value indicating whether the statusbar should be shown or not. :type show: bool """ if show: self.statusBar.show() else: self.statusBar.hide() @pyqtSlot(bool) def toggleFullscreen(self, fullscreen): """Slot for toggling the logger window. :param fullscreen: a boolean value indicating whether to enter fullscreenmode or not. :type fullcreen: bool """ if fullscreen: self.__tmpWinSize = self.size() self.showFullScreen() else: self.showNormal() self.resize(self.__tmpWinSize) def showServerEditor(self): """Slot to display the server editor dialog. """ serverEditor = ServerDialog() r = serverEditor.exec_() if r: #TODO -- only display if plugins open: self.serversChangedMessage.showMessage( QApplication.translate( "MainWindow", "You may need to restart plugins for changes to take effect." )) def showTempPasswordDialog(self): """ Sets overridePassword for a server. Using this one doesn't actually have to enter the password in the ServerDialog (and by extension save to disk). """ serverList = ServerList() # Create a stringlist to be used by the qinputdialog stringList = [] for server in serverList.getTable(): stringList.append(server.name) # Display list of servers (serverString, ok) = QInputDialog.getItem( self, QApplication.translate("MainWindow", "Select server"), QApplication.translate("MainWindow", "Server:"), stringList, editable=False) if ok: server = serverList.getServerObjectByName(serverString) if server != None: # Ask for password (value, ok) = QInputDialog.getText( self, QApplication.translate("MainWindow", "Temporary password"), QApplication.translate("MainWindow", "Enter password:"******"""Slot to display the settings dialog. If the settings dialog returns 1, i.e. the user has clicked the ok button, the loadSettings method is called with mainWin=False, to load the (assumed) newly changed settings. :param tab: The index of the tab to display in the settings dialog. :type tab: int """ #settingsDialog = SettingsDialog(self.currentLanguage, self.languages) settingsDialog = SettingsDialog() if tab < 0: tab = 0 settingsDialog.tabWidget.setCurrentIndex(tab) if settingsDialog.exec_(): self.reloadPlugins() # # We assume that some settings is changed # # if the user clicked the ok button, and # # reloads the application settings # self.__loadSettings(mainWin=False) # # A Hack but it'll do for now # for a in self.langGroup.actions(): # if a.data().toString() == self.currentLanguage: # a.setChecked(True) def configurePlugins(self): """Slot to display the plugins configuration. This currently calls `showSettingsDialog` with tab index set to 2. """ self.showSettingsDialog(1) def reloadPlugins(self): """Slot to reload plugins. """ self.pluginWidget.updatePlugins() def pluginSelected(self, item): """This method will be called from the `PluginListWidget`. """ # Clear the stylesheet when a tab is opened self.__setTabWidgetStyle(self.defaultTabStyle) widget = item.plugin.getPluginWidget(None, self) if platform.system() == "Windows": scroll = QScrollArea() scroll.setWidget(widget) scroll.setWidgetResizable(True) index = self.mainTabs.addTab(scroll, item.icon(), item.plugin.pluginUserString) else: index = self.mainTabs.addTab(widget, item.icon(), item.plugin.pluginUserString) self.mainTabs.setCurrentIndex(index) def tabClose(self, index): """Slot for the signal `tabCloseRequest(int)` for the tabMains. """ widget = self.mainTabs.widget(index) # If the tab closed is one of these, enable the toggle-action if widget == self.pluginWidget: self.actionShowPluginList.setEnabled(True) if widget == self.welcomeTab: self.actionShowWelcomeTab.setEnabled(True) self.mainTabs.removeTab(index) # Unparent the widget since it was reparented by the QTabWidget # so it's garbage collected widget.setParent(None) # In case the widget contained circular references # -- force GC to take care of the objects since there can be # quite many if it was BrowserWidget that was closed. # Can't call it directly since that'll be too soon QTimer.singleShot(1000, self.gc) # Let's do some styling of the tab widget when no tabs are opened if self.mainTabs.currentIndex() == -1: self.__setTabWidgetStyle(self.lumaHeadStyle) def gc(self): """Runs Python's garbage-collection manually. Used to make sure circular references are taken care of *now*. """ gc.collect() def showWelcome(self): """Shows the Welcome-tab """ self.__setTabWidgetStyle(self.defaultTabStyle) index = self.mainTabs.addTab( self.welcomeTab, QApplication.translate("MainWindow", "Welcome")) self.mainTabs.setCurrentIndex(index) self.actionShowWelcomeTab.setEnabled(False) def showPlugins(self): """Will show the pluginlistwidget-tab """ self.__setTabWidgetStyle(self.defaultTabStyle) if self.mainTabs.indexOf(self.pluginWidget) == -1: index = self.mainTabs.addTab( self.pluginWidget, QApplication.translate("MainWindow", "Plugins")) self.mainTabs.setCurrentIndex(index) self.actionShowPluginList.setEnabled(False) def closeEvent(self, e): """Overrides the ``QMainWindow.closeEvent`` slot to save settings before we tear down the application. """ self.__writeSettings() QMainWindow.closeEvent(self, e)
class MSMainWindow(QMainWindow): """Gui of the main window""" #MAX_RECENT_FILES = 10 #start putting links spyder numpy scipy et tutti quanti links=('http://numpy.scipy.org/', 'http://packages.python.org/spyder/', 'http://www.riverbankcomputing.co.uk/software/pyqt/intro') pluginPath=path.normcase('pluginmanager/plugins/') def __init__(self, availablePlugins): """ Constructor with all the models needed setup menus """ QMainWindow.__init__(self) self.setDockOptions(QMainWindow.VerticalTabs | QMainWindow.AnimatedDocks) self.plugins = availablePlugins self.pluginsInst=[] settings=QSettings('INRA/INSA', '-'.join([QApplication.instance().APPLICATION_NAME_STR, QApplication.instance().VERSION_STR])) self.recentFiles = list(settings.value("RecentFiles").toStringList()) self.setStyleSheet(stylesheet) self.pipeline = MSPipelineToolBar("Pipeline toolbar", parent=self) self.addToolBar(0x1,self.pipeline) self._setupModels() self._setupUi() self._setupMenus() def _setupModels(self): """ Warning:Causes segfault when horizontal labels set to True on aura peu etre a la fin un model par sampleList c'est ce qui parait le plus logique """ #drag and drop table sample self.sampleModel = QStandardItemModel(self) self.sampleModel.setHorizontalHeaderLabels(["Sample", "Class"]) #treeView1 self.spectraModel = QStandardItemModel(self) #treeview2 self.peakModel = QStandardItemModel(self) #treeview3 self.clusterModel = QStandardItemModel(self) def _setupMenus(self): #file self.fileMenu = QMenu('&File') self.fileMenu.setTearOffEnabled(True) self.op=QMenu("&Open...",self.fileMenu) self.op.setIcon(QIcon(path.normcase("gui/icons/fileopen.png"))) open_=QAction("&Open rawfiles", self) open_.setToolTip("Open an mzXML or netCDF file") open_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_O)) open_icon=QIcon(path.normcase("gui/icons/fileopen.png")) open_.setIcon(open_icon) self.op.addAction(open_) load_=QAction("&Open projects...", self) load_.setToolTip("load binary file containing saved objects") load_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_S)) load_icon=QIcon(QPixmap(path.normcase("gui/icons/project_open.png"))) load_.setIcon(load_icon) self.op.addAction(load_) self.fileMenu.addMenu(self.op) save_=QAction("&Save...", self) save_.setToolTip("save the actual application model") save_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_S)) save_icon=QIcon(path.normcase("gui/icons/save_all.png")) save_.setIcon(save_icon) self.fileMenu.addAction(save_) pkl = QAction("&load a peaklist", self) #TODO:load peaklist pkl.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_P)) pkl.setToolTip("load a peaklist and process it") pkl.setIcon(QIcon(path.normcase("gui/icons/featuredetect.png"))) self.fileMenu.addAction(pkl) convert_=QAction("&Convert...", self) convert_.setEnabled(False) convert_.setToolTip("Convert a .wiff file if Analyst(c) is installed") convert_icon=QIcon(path.normcase("gui/icons/goto.png")) convert_.setIcon(convert_icon) self.fileMenu.addAction(convert_) a = self.fileMenu.addAction(QIcon(path.normcase("gui/icons/process.png")), "&Launch a batch") a.setEnabled(False) b = self.fileMenu.addAction(QIcon(path.normcase("gui/icons/process.png")), "&Merge") b.setToolTip("Merge MRM file") #b.setEnabled(False) self.fileMenu.addSeparator() # # for i in xrange(self.MAX_RECENT_FILES): # a = QAction('', self) # a.setVisible(False) # self.fileMenu.addAction(a) # # for i in xrange(min(self.MAX_RECENT_FILES, len(self.recentFiles))): # self.fileMenu.actions()[5+i].setVisible(True) # self.fileMenu.actions()[5+i].setText(self.recentFiles[i].split('/')[-1]) exit_action =QAction("&Exit", self) exit_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q)) exit_action.setIcon(QIcon(QPixmap(path.normcase('gui/icons/exit.png')))) self.fileMenu.addAction(exit_action) self.menuBar().addMenu(self.fileMenu) self.editMenu=QMenu("&Edit") self.editMenu.setTearOffEnabled(True) self.editMenu.addAction(QIcon(path.normcase('gui/icons/edit_undo.png')), '&Undo...') self.editMenu.addAction(QIcon(path.normcase('gui/icons/edit_redo.png')), '&Redo...') self.editMenu.actions()[0].setEnabled(False) self.editMenu.actions()[1].setEnabled(False) self.editMenu.addSeparator() self.editMenu.addAction(QIcon(path.normcase('gui/icons/run.png')), '&Preferences') self.exportMenu = QMenu("&Export...") self.exportMenu.setIcon(QIcon(path.normcase('gui/icons/file_export.png'))) self.exportMenu.addAction("&Peaklist") self.exportMenu.addAction("&Clusters intensity matrix") self.editMenu.addMenu(self.exportMenu) self.menuBar().addMenu(self.editMenu) #view self.viewMenu =QMenu("&View") self.viewMenu.setTearOffEnabled(True) self.viewMenu.addAction(QIcon(path.normcase('gui/icons/window_duplicate')), "&Cascade View", self.mdiArea.cascadeSubWindows, QKeySequence(Qt.CTRL + Qt.Key_K)) self.viewMenu.addAction(QIcon(path.normcase('gui/icons/view_icon')), "&Title View", self.mdiArea.tileSubWindows, QKeySequence(Qt.CTRL + Qt.Key_N)) self.viewMenu.addAction(QIcon(path.normcase("gui/icons/stop_process.png")), "&Close all subWindows", self.mdiArea.closeAllSubWindows, QKeySequence(Qt.CTRL+Qt.Key_W)) self.plotting =QMenu("&Plotting...") self.plotting.setIcon(QIcon(QPixmap(path.normcase("gui/icons/plot.png")))) self.plotting.addAction("&3D Plot") #self.plotting.addAction("&Cytoscape web") self.plotting.addAction("&Spectrogram Plot") #self.multiplePlot = QAction("&Visualize Raw/Treated Data", self) #self.multiplePlot.setCheckable(True) #self.multiplePlot.setEnabled(False) #self.sub_plot_.addAction(self.multiplePlot) self.viewMenu.addMenu(self.plotting) self.viewMenu.addSeparator() self.show_hide=QMenu("&Show/Hide") m=self.createPopupMenu() m.setTitle("&Show/Hide") self.viewMenu.addMenu(m) #self.pref = QMenu("&Preferences") #self.pref.addAction(self.multiplePlot) #self.viewMenu.addMenu(self.pref) self.menuBar().addMenu(self.viewMenu) #algorithm self.algoMenu= QMenu("&Algorithm") self.algoMenu.setTearOffEnabled(True) self.preProcessing=QMenu("&PreProcessing(experimental)") self.preProcessing.addAction("&Smoothing raw data...") self.preProcessing.addAction("&Cut off raw data...") self.preProcessing.addAction('&Calibration (mz dimension)') self.preProcessing.addAction("&Resize sample...") self.algoMenu.addMenu(self.preProcessing) self.peakPickingMenu = QMenu("&Peack Picking & Alignement(XCMS)", self) self.peakPickingMenu.setIcon(QIcon(path.normcase("gui/icons/pickedpeakicon.png"))) matched = QAction("&MatchedFiltered", self) matched.setIcon(QIcon(path.normcase('gui/icons/RLogo'))) matched.setToolTip("Peak Detection and Integration using MatchedFiltered algorithm") self.peakPickingMenu.addAction(matched) centwave=QAction("&CentWave", self) centwave.setIcon(QIcon(path.normcase('gui/icons/RLogo'))) centwave.setToolTip("Peak Detection and Integration using CentWave algorithm") self.peakPickingMenu.addAction(centwave) #peak_.setShortcut(.QKeySequence(CTRL + Key_P)) # peak_icon=.QIcon(.QPixmap(path.normcase("gui/icons/pickedpeakicon.png"))) #peak_.setIcon(peak_icon) self.algoMenu.addMenu(self.peakPickingMenu) self.alignment = QMenu("&Alignment") self.alignment.setIcon(QIcon(path.normcase('gui/icons/format_indent_more.png'))) self.alignment.addAction("&Polynomial fitting(exp)") self.alignment.addAction("&DynamicTimeWarping") self.alignment.addAction("&ObiWarp") self.alignment.actions()[2].setEnabled(False) self.algoMenu.addMenu(self.alignment) self.algoMenu.addAction("Normalization") clust_ = QAction("&Clustering", self) clust_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_L)) clust_icon=QIcon(QPixmap(path.normcase("gui/icons/cluster.png"))) clust_.setIcon(clust_icon) self.algoMenu.addAction(clust_) id_ = QAction("&Identification", self) id_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_I)) id_.setToolTip("Try to identify peaks with several methods") id_.setIcon(QIcon(QPixmap(path.normcase("gui/icons/findcompound.png")))) self.algoMenu.addAction(id_) self.menuBar().addMenu(self.algoMenu) #tools self.toolsMenu =QMenu("&Tools") self.toolsMenu.setTearOffEnabled(True) web = QAction("&Web Browser", self) web.setIcon(QIcon(QPixmap(path.normcase("gui/icons/applications_internet.png")))) self.toolsMenu.addAction(web) #cyto = QAction("&cytoscape", self) #cyto_icon =QIcon(QPixmap(path.normcase("gui/icons/cytoscape.jpeg"))) #cyto.setIcon(cyto_icon) #self.toolsMenu.addAction(cyto) editor = QAction("&Editor", self) editor.setIcon(QIcon(QPixmap(path.normcase("gui/icons/document_sign.png")))) self.toolsMenu.addAction(editor) pet=QAction("&Short Periodic Table", self) pet.setIcon(QIcon(QPixmap(path.normcase("gui/icons/pet.jpg")))) self.toolsMenu.addAction(pet) self.menuBar().addMenu(self.toolsMenu) #plugins self.pluginMenu = QMenu('&Plugins') self.pluginMenu.setTearOffEnabled(True) instPl= QAction("&Install a plugin", self) instPl.setIcon(QIcon(path.normcase('gui/icons/pluginInstall.png'))) self.pluginMenu.addAction(instPl) self.launchingMenu = QMenu("&Launch PLugins", self) self.launchingMenu.setIcon(QIcon(path.normcase('gui/icons/plugin'))) for plug in self.plugins: #fullname="".join([self.pluginPath, str(plug)]) mod=imp.load_source(self.__module__, plug) if mod.autoActivation: qApp=QApplication.instance() name=getattr(mod, 'className') cls=getattr(mod, name) p=cls(qApp.model, self, parent=self) #p=qApp.pluginManager.loadPlugin(qApp.model, self, plug.split('/')[-1]) self.pluginsInst.append(p) else: self.launchingMenu.addAction(plug.split('/')[-1]) self.pluginMenu.addMenu(self.launchingMenu) self.pluginMenu.addAction(QIcon(path.normcase("gui/icons/process_stop.png")), "&Remove loaded Plugin") self.menuBar().addMenu(self.pluginMenu) #about self.aboutMenu= QMenu("&About") self.aboutMenu.setTearOffEnabled(True) metms = QAction(QIcon(path.normcase('gui/icons/deluge.png')), "&about metMS...", self) self.aboutMenu.addAction(metms) pyqt = QAction("&about PyQt4...", self) pyqt_icon =QIcon(QPixmap(path.normcase("gui/icons/logo_QT4.png"))) pyqt.setIcon(pyqt_icon) self.aboutMenu.addAction(pyqt) metms = QAction("&metMS Documentation", self) metms_icon =QIcon(QPixmap(path.normcase("gui/icons/deluge.png"))) metms.setIcon(metms_icon) self.aboutMenu.addAction(metms) self.menuBar().addMenu(self.aboutMenu) def _setupUi(self, background=None): """ Make the GUI """ #mdi self.mdiArea = MSMdiArea(self) self.mdiArea.setBackground(QBrush(QPixmap(path.normcase('gui/icons/blac2.png'))))#QColor(Qt.blue).darker())) self.setCentralWidget(self.mdiArea) #sample dock widget self.sampleDockWidget = QDockWidget("Samples", self) #sampleWidget = QWidget() self.sampleTableView = MSDragFromTableView() self.sampleTableView.setModel(self.sampleModel) self.sampleTableView.setSelectionBehavior(1) self.sampleTableView.verticalHeader().hide() self.sampleTableView.verticalHeader().setDefaultSectionSize(15) self.sampleTableView.horizontalHeader().setDefaultSectionSize(150) self.sampleDockWidget.setWidget(self.sampleTableView)#sampleWidget) self.sampleDockWidget.visible=True #workflow dock self.workflowDockWidget = QDockWidget("Visualizer", self) self.workflowDockWidget.visible = True a=QWidget(self) v=QVBoxLayout(a) q=QToolBar() #self.workingSample = QLabel("Working Sample:None") #q.addWidget(self.workingSample) q.addWidget(QLabel("ppm :")) self.ppmEditer=QDoubleSpinBox() self.usePpm=QCheckBox("use ?") q.addWidget(self.ppmEditer) q.addWidget(self.usePpm) q.addSeparator() self.removeButton=QToolButton(self) self.removeButton.setIcon(QIcon(path.normcase("gui/icons/delete.png"))) q.addWidget(self.removeButton) self.markAsGood=QAction(QIcon(path.normcase("gui/icons/button_ok.png")),"mark peak as good", self) self.markAsBad=QAction(QIcon(path.normcase("gui/icons/stop.png")), "mark peak as bad", self) self.hideItem = QAction(QIcon(path.normcase("gui/icons/list_remove.png")), "Hide Item", self) q.addAction(self.markAsGood) q.addAction(self.markAsBad) q.addAction(self.hideItem) v.addWidget(q) self.tabWidget = QTabWidget() self.tab = QWidget() verticalLayout = QVBoxLayout(self.tab) self.treeView = MSToDropTableView() self.treeView.verticalHeader().setDefaultSectionSize(20) self.treeView.setModel(self.spectraModel) self.spectraLabel = QLabel("Sample: None") verticalLayout.addWidget(self.treeView) verticalLayout.addWidget(self.spectraLabel) self.tabWidget.addTab(self.tab, QIcon(path.normcase("gui/icons/spectrumicon.png")),"Spectra") self.tab_2 = QWidget() verticalLayout_4 = QVBoxLayout(self.tab_2) self.treeView_2 = MSToDropTableView()#MSTreeView(self.tab_2)# QTableView(self)# self.treeView_2.verticalHeader().setDefaultSectionSize(20) self.treeView_2.setModel(self.peakModel) self.peakLabel = QLabel("Sample: None") verticalLayout_4.addWidget(self.treeView_2) verticalLayout_4.addWidget(self.peakLabel) self.tabWidget.addTab(self.tab_2,QIcon(path.normcase("gui/icons/peakicon.png")), "Peaks List") self.tab_3 = QWidget() verticalLayout_5 = QVBoxLayout(self.tab_3) self.treeView_3 = MSToDropTreeView() self.treeView_3.setAnimated(True) self.treeView_3.setModel(self.clusterModel) self.clusterLabel = QLabel("Sample: None") verticalLayout_5.addWidget(self.treeView_3) verticalLayout_5.addWidget(self.clusterLabel) self.tabWidget.addTab(self.tab_3, QIcon(path.normcase("gui/icons/clustering.png")), "Clusters") self.tabWidget.setCurrentIndex(0) for l in (self.spectraLabel, self.peakLabel, self.clusterLabel): l.setAutoFillBackground(True) v.addWidget(self.tabWidget) self.workflowDockWidget.setWidget(a) self.addDockWidget(Qt.DockWidgetArea(0x2),self.workflowDockWidget) from gui.MetBaseGui import MSIsoCalculator self.isoCalc = MSIsoCalculator(self) self.isoCalcDockWidget=QDockWidget('isotopes calculation', self) self.isoCalcDockWidget.setWidget(self.isoCalc) self.addDockWidget(Qt.DockWidgetArea(0x2), self.isoCalcDockWidget) self.isoCalcDockWidget.setVisible(False) self.isoCalcDockWidget.visible=False from gui.MetBaseGui import FormulaGenerator self.generator=FormulaGenerator(self) self.generatorDockWidget=QDockWidget('formula generator', self) self.generatorDockWidget.setWidget(self.generator) self.addDockWidget(Qt.DockWidgetArea(0x2), self.generatorDockWidget) self.generatorDockWidget.setVisible(False) self.generatorDockWidget.visible=False self.compoundTreeView = MSCompoundTreeView(self) self.compoundDockWidget = QDockWidget("Compounds", self) self.compoundDockWidget.setWidget(self.compoundTreeView) self.addDockWidget(Qt.DockWidgetArea(0x2),self.compoundDockWidget) self.compoundDockWidget.setVisible(False) self.compoundDockWidget.visible=False self.comparativeTableView = QTableView(self) self.comparativeTableView.horizontalHeader().setStretchLastSection(True) self.comparativeTableView.verticalHeader().setDefaultSectionSize(20) self.comparativeDock = QDockWidget("Comparative View", self) self.comparativeDock.setWidget(self.comparativeTableView) self.addDockWidget(Qt.DockWidgetArea(0x8), self.comparativeDock) self.comparativeDock.setVisible(False) self.comparativeDock.visible = False self.tabifyDockWidget(self.compoundDockWidget, self.isoCalcDockWidget) self.tabifyDockWidget(self.isoCalcDockWidget, self.workflowDockWidget ) self.tabifyDockWidget(self.workflowDockWidget, self.generatorDockWidget) #set the end #WARNING: possible that the internal shell widget cause random segfault #with the error of QObject::killTimers...? not sure ! self.shell = QWidget()#InternalShell(namespace={'metms': QApplication.instance()}, # parent=self, # multithreaded=False) self.shellDock = QDockWidget("Python Shell", self) self.shellDock.setWindowIcon(QIcon(path.normcase('gui/icons/stop.png'))) self.shellDock.setWidget(self.shell) self.shellDock.setMinimumWidth(255) self.shellDock.visible=True self.addDockWidget(0x2, self.shellDock) self.addDockWidget(0x2, self.sampleDockWidget) self.tabifyDockWidget(self.shellDock, self.sampleDockWidget) self.pb = QProgressBar(self) self.pb.setMaximumWidth(245) self.stopProcess = QToolButton(self) self.stopProcess.setIcon(QIcon(path.normcase("gui/icons/process_stop.png"))) m = QMenu() #self.connect(m, SIGNAL('triggered(QAction*'), QApplication.instance().taskManager.abortByName) self.stopProcess.setMenu(m) self.stopProcess.setPopupMode(1) #Menu Button #self.connect(self.stopProcess, SIGNAL("clicked()"), self.stopThread) self.statusBar().addPermanentWidget(self.stopProcess) self.statusBar().addPermanentWidget(self.pb) def updateStopProcessMenu(self): """ update the menu of the stop process button, based directly on the processes stored by the task manager """ self.stopProcess.menu().clear() for c in QApplication.instance().taskManager: self.stopProcess.menu().addAction(c.title) #QApplication.instance().taskManager.abort(QApplication.instance().taskManager[-1]) def addMdiSubWindow(self, plot, title="", showMaximized=False): """ Allow addition of new window in the mdiarea """ win=self.mdiArea.addSubWindow(plot) #print "widget parent", plot.parent() win.setAttribute(Qt.WA_DeleteOnClose) #win.connect(win, SIGNAL('destroyed(QObject *)'), self.testdestroy) #plot.setParent(win) win.setWindowTitle(title) if showMaximized: win.showMaximized() else: win.resize(400, 300) win.show() return win def updateTreeView(self): """ Tree View update switch spectre/chromato """ if self.treeView.model() == self.spectraModel: self.treeView.setModel(self.chromaModel) self.tabWidget.setTabText(0, "Chroma") else: self.treeView.setModel(self.spectraModel) #self.treeView.setSelectionMode(1) self.tabWidget.setTabText(0, "Spectra") def addTreeViewModel (self,model1, model2): """Add a model """ self.chromaModel.appendRow(model1) self.spectraModel.appendRow(model2) def _actionHovered(self, action): """emulate tooltip cause they do not work that much""" tip = action.toolTip() QToolTip.showText(QCursor.pos(), tip) def showErrorMessage(self, title, string): QMessageBox.critical(self, title, string, 0, 0) def showWarningMessage(self, title, string): return QMessageBox.warning(self, title, string, QMessageBox.Ok|QMessageBox.Cancel) def showInformationMessage(self, title, string): QMessageBox.information(self, title, string, 0) def updateProgressBar(self, i): """update the value of the progress bar for all the treatment""" self.pb.setValue(min(i, 100)) def to_indetermined_mode(self): self.pb.setMaximum(0) def to_determined_mode(self): self.pb.setMaximum(100) def showInStatusBar(self, string, time=5000): self.statusBar().showMessage(string, time) def addInterpreterDock(self, shell): self.shellDock = QDockWidget(self) self.shellDock.setWidget(shell) self.shellDock.setWindowTitle("shell") self.addDockWidget(0x2, self.shellDock) def showMetMSInformation(self): QMessageBox.about(self, self.tr("About %1").arg("metMS"), self.tr("""<b>%1 %2</b> <br>metabolite Mass Spectrometry <p>Copyright © 2010 Marco INSA, INRA <br>Licensed under the terms of the CeciLL License <p>Developed and maintained by Marco <br>Bug reports and feature requests: <a href="http://github.com/jerkos/metms">metMS site</a><br> Discussions around the project: <a href="http://groups.google.com/group/spyderlib">Google Group</a> <p>This project is part of the BRIDGE project <p>Python %3, Qt %4, PyQt %5""") \ .arg("metMS").arg(__version__) \ .arg(platform.python_version()).arg(QT_VERSION_STR) \ .arg(PYQT_VERSION_STR))
class GUI(QMainWindow): def __init__(self, debug=False): QMainWindow.__init__(self) # initialise filename self.filename = None # make the data store from xmlstore import Store self.store = Store(debug=debug) # view the current table self.tableView = TableView(self) #self.tableView.setDragEnabled(True); #self.tableView.setDragDropMode(QAbstractItemView.InternalMove) #self.tableView.setAcceptDrops(True); #self.tableView.setDropIndicatorShown(True); self.tableView.verticalHeader().sectionMoved.connect(self.sectionMoved) self.tableView.verticalHeader().setMovable(True) self.setCentralWidget(self.tableView) # add a custom delegate to it self.delegate = ComboBoxDelegate() self.tableView.setItemDelegate(self.delegate) # dock the table selection on the left self.dock1 = QDockWidget(self) self.listView = ListView(self) self.listView.setDragEnabled(True) self.listView.setDragDropMode(QAbstractItemView.InternalMove) self.listView.setDropIndicatorShown(True) self.dock1.setWidget(self.listView) self.dock1.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.addDockWidget(Qt.LeftDockWidgetArea, self.dock1) # connect it to the populate method self.connect(self.listView, SIGNAL('activated ( const QModelIndex & )'), self.populate) self.connect(self.listView, SIGNAL('clicked ( const QModelIndex & )'), self.populate) # dock the undoView on the left self.dock2 = QDockWidget(self) self.undoView = QUndoView(self.store.stack) self.dock2.setWidget(self.undoView) self.dock2.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock2.setWindowTitle('Undo Stack') self.addDockWidget(Qt.LeftDockWidgetArea, self.dock2) # create a menubar self.menu = self.menuBar() # create file menu headings self.menuFile = self.menu.addMenu('File') self.menuFile.addAction('New', self.New).setShortcut('CTRL+N') self.menuFile.addAction('Open...', self.Open).setShortcut('CTRL+O') self.menuFile.addAction('Reload', self.Reload) self.menuFile.addAction('Save', self.Save).setShortcut('CTRL+S') self.menuFile.addAction('Save As...', self.SaveAs) self.menuFile.addSeparator() self.menuFile.addAction('Set Architecture...', self.setArch) self.menuFile.addSeparator() self.menuFile.addAction('Quit', self.closeEvent).setShortcuts( ['CTRL+Q', 'ALT+F4']) # create edit menu headings self.menuEdit = self.menu.addMenu('Edit') self.menuEdit.addAction('Insert Row', self.tableView.insertRow).setShortcut('CTRL+I') self.menuEdit.addAction( 'Insert Row Under', self.tableView.insertRowUnder).setShortcut('CTRL+U') self.menuEdit.addAction('Remove Row', self.tableView.removeRow) self.menuEdit.addSeparator() self.menuEdit.addAction('Cut', self.tableView.cut).setShortcut('CTRL+X') self.menuEdit.addAction('Copy', self.tableView.copy).setShortcuts( ['CTRL+C', 'CTRL+INS']) self.menuEdit.addAction('Paste', self.tableView.paste).setShortcuts( ['CTRL+V', 'SHIFT+INS']) self.menuEdit.addAction('Clear', self.tableView.menuClear).setShortcut('CTRL+D') self.menuEdit.addSeparator() self.menuEdit.addAction('Fill Cells', self.tableView.fillCells).setShortcut('CTRL+L') self.menuEdit.addAction( 'Fill Cells and Increment', self.tableView.fillCellsInc).setShortcut('CTRL+R') self.menuEdit.addAction( 'Python Code...', self.tableView.pythonCode).setShortcut('CTRL+P') self.tableView.codeBox = pythonCode() self.menuEdit.addSeparator() self.menuEdit.addAction('Undo', self.store.stack, SLOT('undo()')).setShortcut('CTRL+Z') self.menuEdit.addAction('Redo', self.store.stack, SLOT('redo()')).setShortcut('CTRL+SHIFT+Z') # create component menu self.menuComponents = self.menu.addMenu('Components') self.resize(QSize(1000, 500)) def Save(self): # save menu command self.SaveAs(self.filename) def setArch(self): arch = self.store.getArch() arch, ok = QInputDialog.getText(self, 'Architecture Dialog', 'Enter Architecture', QLineEdit.Normal, arch) arch = str(arch) if ok: self.store.setArch(arch) def SaveAs(self, filename=''): # save as menu command if filename == '': filename = str(QFileDialog.getSaveFileName()) if filename != '': self.filename = filename self.store.Save(filename) self._setClean() def Reload(self): if self.filename is not None: self.Open(self.filename, name=self.tablename) def Open(self, filename='', name=None): # make sure the user is sure if there are unsaved changes if self.__prompt_unsaved() == QMessageBox.Cancel: return # ask for a filename if filename == '': filename = str( QFileDialog.getOpenFileName( filter="Xml Files (*.xml);;All files (*.*)")) if filename == '': return # store the filename self.filename = filename # tell the store to open a new set of tables try: problems, warnings = self.store.Open(filename) if problems: errorstr = 'Can\'t load all object types: ' + ', '.join( problems) QMessageBox.warning(self, 'Open Error', errorstr) if warnings: errorstr = \ 'The following warnings were generated:\n' + \ '\n'.join(warnings) QMessageBox.warning(self, 'Open Warnings', errorstr) except Exception, e: x = formLog( 'An error ocurred. Make sure all the modules listed ' 'in RELEASE files are built. Check the text below for ' 'details:\n\n' + traceback.format_exc(), self) x.show() return # populate self.setWindowTitle('XEB - %s[*]' % filename) self.listView.clear() for t in self.store.getTableNames(): self.__insertListViewItem(t) self.__populateMenu() self.populate(name=name) self._setClean()
class Main(plugin.Plugin): " Main Class " def initialize(self, *args, **kwargs): " Init Main Class " super(Main, self).initialize(*args, **kwargs) self.chooser, self.process = QComboBox(), QProcess() self.chooser.addItems([' Ubuntu Unity QuickList .desktop ', ' KDE Plasma MetaData .desktop ', ' FreeDesktop Standard .desktop ']) self.chooser.currentIndexChanged.connect(self.on_index_changed) self.chooser.setToolTip('Select a target .desktop file format') # Standard FreeDesktop self.group1 = QGroupBox() self.group1.setTitle(' Standard ') self.ledVersion, self.ledCategories = QDoubleSpinBox(), QComboBox() self.ledVersion.setMinimum(0.1) self.ledVersion.setMaximum(999.9) self.ledVersion.setValue(1.0) self.ledVersion.setDecimals(1) self.ledType, self.ledName = QLineEdit('Application'), QLineEdit('App') self.ledGenericName = QLineEdit('Generic App') self.ledComment, self.ledIcon = QLineEdit('App'), QLineEdit('icon.svg') self.ledCategories.addItems(['Python Programming Language', 'Development', 'Ruby', 'C++', 'Amateur Radio', 'Communication', 'Cross Platform', 'Databases', 'Debug', 'Documentation', 'Editors', 'Education', 'Electronics', 'Email', 'Embebed Devices', 'Fonts', 'GNOME Desktop Environment', 'GNU R Statistical System', 'GObject Introspection Data', 'Games and Amusement', 'Gnustep Desktop Environtment', 'Graphics', 'Haskell Programming Language', 'Internationalization and Localization', 'Internet', 'Interpreted Computer Languages', 'KDE Software Compilation', 'Kernel and Modules', 'Libraries', 'Libraries - Development', 'Libraries - Old', 'Lisp Programming Language', 'Localization', 'Mathematics', 'Meta Packages', 'Miscelaneous - Graphical', 'Miscelaneous - Text Based', 'Mono/CLI Infraestructure', 'Multimedia', 'Networking', 'Newsgroups', 'OCaml Programming Language', 'PHP Programming Language', 'Perl Programming Language', 'Ruby Programming Language', 'Science', 'Shells', 'System Administration', 'TeX Authoring', 'Utilities', 'Version Control Systems', 'Video Software', 'Web Servers', 'Word Processing', 'Xfce Desktop Environment', 'Zope/Plone Environment']) self.ledExec, self.ledTryExec = QLineEdit('myapp'), QLineEdit('myapp') self.ledMymeType = QLineEdit('application/x-desktop') self.ledTerminal = QComboBox() self.ledTerminal.addItems(['False', 'True']) self.ledActions = QLineEdit('Next;Previous') self.ledOnlyShowIn = QLineEdit('Unity;KDE') self.ledNotShowIn = QLineEdit('Gnome2') vboxg1 = QVBoxLayout(self.group1) for each_widget in (QLabel('Version'), self.ledVersion, QLabel('Type'), self.ledType, QLabel('Name'), self.ledName, QLabel('GenericName'), self.ledGenericName, QLabel('Comment'), self.ledComment, QLabel('Icon'), self.ledIcon, QLabel('Categories'), self.ledCategories, QLabel('Exec'), self.ledExec, QLabel('TryExec'), self.ledTryExec, QLabel('MymeType'), self.ledMymeType, QLabel('Terminal'), self.ledTerminal, QLabel('Actions'), self.ledActions, QLabel('OnlyShowIn'), self.ledOnlyShowIn, QLabel('NotShowIn'), self.ledNotShowIn): vboxg1.addWidget(each_widget) # KDE Plasma self.group2 = QGroupBox() self.group2.setTitle(' KDE Plasma ') self.group2.setGraphicsEffect(QGraphicsBlurEffect(self)) self.ledEncoding, self.ledXPlasmaAPI = QComboBox(), QComboBox() self.ledEncoding.addItems(['UTF-8', 'ISO-8859-1']) self.ledServiceType = QLineEdit('Plasma/Applet') self.ledXPlasmaAPI.addItems([ 'Python', 'Javascript', 'Ruby', 'C++', 'HTML5', 'QML']) self.ledXPlasmaMainScript = QLineEdit('path/to/your/code.py') self.ledXKDEPluginInfoAuthor = QLineEdit(getuser()) self.ledXKDEPluginInfoEmail = QLineEdit(getuser() + '@gmail.com') self.ledXKDEPluginInfoName = QLineEdit('Hello-World') self.ledXKDEPluginInfoVersion = QLineEdit('1.0') self.ledXKDEPluginInfoWebsite = QLineEdit('http:plasma.kde.org') self.ledXKDEPluginInfoCategory = QComboBox() self.ledXKDEPluginInfoCategory.addItems(['Application Launchers', 'Accessibility', 'Astronomy', 'Date and Time', 'Development Tools', 'Education', 'Environment', 'Examples', 'File System', 'Fun and Games', 'Graphics', 'Language', 'Mapping', 'Multimedia', 'Online Services', 'System Information', 'Utilities', 'Windows and Tasks', 'Miscelaneous']) self.ledXKDEPluginInfoDepends = QLineEdit() self.ledXKDEPluginInfoLicense = QLineEdit('GPL') self.ledXKDEPluginInfoEnabledByDefault = QComboBox() self.ledXKDEPluginInfoEnabledByDefault.addItems(['True', 'False']) vboxg2 = QVBoxLayout(self.group2) for each_widget in ( QLabel('Encoding'), self.ledEncoding, QLabel('ServiceType'), self.ledServiceType, QLabel('X-Plasma-API'), self.ledXPlasmaAPI, QLabel('X-Plasma-MainScript'), self.ledXPlasmaMainScript, QLabel('X-KDE-PluginInfo-Author'), self.ledXKDEPluginInfoAuthor, QLabel('X-KDE-PluginInfo-Email'), self.ledXKDEPluginInfoEmail, QLabel('X-KDE-PluginInfo-Name'), self.ledXKDEPluginInfoName, QLabel('X-KDE-PluginInfo-Version'), self.ledXKDEPluginInfoVersion, QLabel('X-KDE-PluginInfo-Website'), self.ledXKDEPluginInfoWebsite, QLabel('X-KDE-PluginInfo-Category'), self.ledXKDEPluginInfoCategory, QLabel('X-KDE-PluginInfo-Depends'), self.ledXKDEPluginInfoDepends, QLabel('X-KDE-PluginInfo-License'), self.ledXKDEPluginInfoLicense, QLabel('X-KDE-PluginInfo-EnabledByDefault'), self.ledXKDEPluginInfoEnabledByDefault): vboxg2.addWidget(each_widget) # Ubuntu Unity self.ledXAyatanaDesktopShortcuts = QLineEdit('Next;Previous') self.checkbox1 = QCheckBox('Open .desktop file when done') self.checkbox2 = QCheckBox('Make .desktop file Executable') [a.setChecked(True) for a in (self.checkbox1, self.checkbox2)] self.button = QPushButton(' Make .Desktop File ! ') self.button.setMinimumSize(100, 50) self.button.clicked.connect(self.writeFile) glow = QGraphicsDropShadowEffect(self) glow.setOffset(0) glow.setBlurRadius(99) glow.setColor(QColor(99, 255, 255)) self.button.setGraphicsEffect(glow) glow.setEnabled(True) class TransientWidget(QWidget): ' persistant widget thingy ' def __init__(self, widget_list): ' init sub class ' super(TransientWidget, self).__init__() vbox = QVBoxLayout(self) for each_widget in widget_list: vbox.addWidget(each_widget) tw = TransientWidget((self.chooser, self.group1, self.group2, QLabel('X-Ayatana-Desktop-Shortcuts'), self.ledXAyatanaDesktopShortcuts, QLabel(''), self.checkbox1, self.checkbox2, self.button)) self.dock, self.scrollable = QDockWidget(), QScrollArea() self.scrollable.setWidgetResizable(True) self.scrollable.setWidget(tw) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.dock.setWidget(self.scrollable) ExplorerContainer().addTab(self.dock, "DotDesktop") QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock ).clicked.connect(lambda: QMessageBox.information(self.dock, __doc__, ''.join((__doc__, __version__, __license__, 'by', __author__)))) def writeFile(self): ' write the .desktop file to disk ' UNITY = ''.join(a for a in iter(( 'OnlyShowIn=', str(self.ledOnlyShowIn.text()), linesep, 'NotShowIn=', str(self.ledNotShowIn.text()), linesep, 'X-Ayatana-Desktop-Shortcuts=', str(self.ledXAyatanaDesktopShortcuts.text()), linesep))) PLASMA = ''.join(a for a in iter(( 'OnlyShowIn=', str(self.ledOnlyShowIn.text()), linesep, 'NotShowIn=', str(self.ledNotShowIn.text()), linesep, 'Encoding=', str(self.ledEncoding.currentText()), linesep, 'ServiceTypes=', str(self.ledServiceType.text()), linesep, 'X-Plasma-API=', str(self.ledXPlasmaAPI.currentText()), linesep, 'X-Plasma-MainScript=', str(self.ledXPlasmaMainScript.text()), linesep, 'X-KDE-PluginInfo-Author=', str(self.ledXKDEPluginInfoAuthor.text()), linesep, 'X-KDE-PluginInfo-Email=', str(self.ledXKDEPluginInfoEmail.text()), linesep, 'X-KDE-PluginInfo-Name=', str(self.ledXKDEPluginInfoName.text()), linesep, 'X-KDE-PluginInfo-Version=', str(self.ledXKDEPluginInfoVersion.text()), linesep, 'X-KDE-PluginInfo-Website=', str(self.ledXKDEPluginInfoWebsite.text()), linesep, 'X-KDE-PluginInfo-Category=', str(self.ledXKDEPluginInfoCategory.currentText()), linesep, 'X-KDE-PluginInfo-Depends=', str(self.ledXKDEPluginInfoDepends.text()), linesep, 'X-KDE-PluginInfo-License=', str(self.ledXKDEPluginInfoLicense.text()), linesep, 'X-KDE-PluginInfo-EnabledByDefault=', str(self.ledXKDEPluginInfoEnabledByDefault.currentText()), linesep))) BASE = ''.join(a for a in iter(( '[Desktop Entry]', linesep, 'Version=', str(self.ledVersion.value()), linesep, 'Type=', str(self.ledType.text()), linesep, 'Name=', str(self.ledName.text()), linesep, 'Comment=', str(self.ledComment.text()), linesep, 'TryExec=', str(self.ledTryExec.text()), linesep, 'Exec=', str(self.ledExec.text()), linesep, 'Icon=', str(self.ledIcon.text()), linesep, 'MimeType=', str(self.ledMymeType.text()), linesep, 'Actions=', str(self.ledActions.text()), linesep, 'Terminal=', str(self.ledTerminal.currentText()), linesep))) ACTIONS * len(str(self.ledActions.text()).lower().strip().split(';')) fnm = str(QFileDialog.getSaveFileName(self.dock, '', '', "(*.desktop)")) with open(fnm, 'w') as f: if self.chooser.currentIndex() is 0 and fnm is not '': f.write(''.join(a for a in iter((BASE, UNITY, ACTIONS)))) elif self.chooser.currentIndex() is 1 and fnm is not '': f.write(''.join(a for a in iter((BASE, PLASMA)))) elif fnm is not '': f.write(BASE) if self.checkbox2.isChecked() and fnm is not '': try: chmod(fnm, 0775) # Py2 except: chmod(fnm, 0o775) # Py3 if self.checkbox1.isChecked() and fnm is not '': self.process.start('ninja-ide ' + fnm) if not self.process.waitForStarted(): print((" ERROR: FAIL: {} failed!".format(fnm))) return def on_index_changed(self): ' enable disable the qgroupbox if needed ' if self.chooser.currentIndex() is 1: self.group2.graphicsEffect().setEnabled(False) self.group2.setEnabled(True) else: self.group2.graphicsEffect().setEnabled(True) self.group2.setEnabled(False) if self.chooser.currentIndex() is 0: self.ledXAyatanaDesktopShortcuts.setEnabled(True) else: self.ledXAyatanaDesktopShortcuts.setEnabled(False)
class filexplorerPluginMain(plugin.Plugin): ' main class for plugin ' def initialize(self, *args, **kwargs): ' class init ' global CONFIG_DIR ec = ExplorerContainer() super(filexplorerPluginMain, self).initialize(*args, **kwargs) self.dock = QDockWidget() self.dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.dock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock.setWindowTitle("fileXplorer") self.dock.setStyleSheet('QDockWidget::title { text-align: center; }') # search for the truth self.srch = QLineEdit() #self.srch.resize(self.srch.size().height(), self.dock.size().width()) self.srch.setPlaceholderText(' Search for Python files Local or PyPI ') self.srch.returnPressed.connect(self.search) # Disk Usage Bar self.hdbar = QProgressBar() if sys.platform != 'win32': self.hdbar.setMaximum(statvfs(HOME).f_blocks * statvfs(HOME).f_frsize / 1024 / 1024 / 1024) self.hdbar.setValue(statvfs(HOME).f_bfree * statvfs(HOME).f_frsize / 1024 / 1024 / 1024) self.hdbar.setToolTip(str(self.hdbar.value()) + '% Total Disk Use ') #self.hdbar.setStyleSheet('''QProgressBar{background-color: #QLinearGradient(spread:pad,x1:0,y1:0,x2:1,y2:1,stop:0 rgba(255,0,0,99), #stop:1 rgba(9,255,9,200));color:#fff;border:none;border-radius:9px;} #QProgressBar::chunk{background-color:QLinearGradient(spread:pad,y1:0, #x1:0,y2:1,x2:0.27,stop:0 rgb(0,0,0),stop:1 rgb(9,99,255));padding:0; #border:none;border-radius:9px;height:9px;margin:1px;}''') self.model = QDirModel() self.fileView = QColumnView(self.dock) self.fileView.setAlternatingRowColors(True) # self.fileView.setFont(QFont(self.fileView.font().setBold(True))) self.fileView.setIconSize(QSize(32, 32)) self.fileView.setModel(self.model) self.fileView.updatePreviewWidget.connect(self.runfile) self.sli = QSlider() self.sli.setRange(16, 128) self.sli.setValue(32) self.sli.setToolTip('Icon Size: 32 px. Move Slider to change.') self.sli.setOrientation(Qt.Horizontal) self.sli.valueChanged.connect(lambda: self.fileView.setIconSize( QSize(self.sli.value(), self.sli.value()))) self.sli.sliderReleased.connect(lambda: self.sli.setToolTip('Icon Size: ' + str(self.sli.value()))) class TransientWidget(QWidget): ' persistant widget thingy ' def __init__(self, widget_list): ' init sub class ' super(TransientWidget, self).__init__() vbox = QVBoxLayout(self) for each_widget in widget_list: vbox.addWidget(each_widget) tw = TransientWidget((self.srch, self.dock, self.sli, self.hdbar)) ec.addTab(tw, "fileXplorer") #### self.process = QProcess() self.process.finished.connect(self.processFinished) self.preview = QLabel(self.fileView) self.preview.setTextFormat(0) self.preview.setStyleSheet('QLabel{font-size:9px;}') self.preview.setAutoFillBackground(True) self.fileView.setPreviewWidget(self.preview) self.dock.setWidget(self.fileView) # take a shot self.pic = QAction(QIcon.fromTheme("camera-photo"), 'Screenshot', self) self.pic.triggered.connect(lambda: QPixmap.grabWindow( QApplication.desktop().winId()).save(QFileDialog.getSaveFileName( self.dock, " Save Screenshot As ... ", HOME, ';;(*.png)'))) # copy time self.tim = QAction(QIcon.fromTheme("user-away"), 'Date and Time to Clipboard', self) self.tim.triggered.connect(lambda: QApplication.clipboard().setText( datetime.now().strftime(" %A %B %d-%m-%Y %H:%M:%S %p "))) # color chooser self.cl = QAction(QIcon.fromTheme("applications-graphics"), 'Color Chooser to Clipboard', self) self.cl.triggered.connect(lambda: QApplication.clipboard().setText( '{}'.format(QColorDialog.getColor().name()))) # icon chooser self.icn = QAction(QIcon.fromTheme("insert-image"), 'Icon Chooser to Clipboard', self) self.icn.triggered.connect(self.iconChooser) # tool bar with actions QToolBar(self.dock).addActions((self.cl, self.icn, self.tim, self.pic)) self.textBrowser = QTextBrowser(self.dock) self.textBrowser.setAutoFillBackground(True) self.textBrowser.setGeometry(self.dock.geometry()) self.textBrowser.hide() def processFinished(self): ' print info of finished processes ' print(" INFO: OK: QProcess finished . . . ") def search(self): ' function to search python files ' # get search results of python filenames local or remote pypi_url = 'http://pypi.python.org/pypi' # pypi query pypi = xmlrpclib.ServerProxy(pypi_url, transport=ProxyTransport()) try: pypi_query = pypi.search({'name': str(self.srch.text()).lower()}) pypi_fls = list(set(['pypi.python.org/pypi/' + a['name'] + ' | pip install ' + a['name'] for a in pypi_query])) except: pypi_fls = '<b> ERROR: Internet not available! ಠ_ಠ </b>' s_out = ('<br> <br> <br> <h3> Search Local Python files: </h3> <hr> ' + # Jedi list comprehension for LOCAL search str(["{}/{}".format(root, f) for root, f in list(itertools.chain(* [list(itertools.product([root], files)) for root, dirs, files in walk(str( QFileDialog.getExistingDirectory(self.dock, 'Open Directory to Search', path.expanduser("~"))))])) if f.endswith(('.py', '.pyw', '.pth')) and not f.startswith('.') and str(self.srch.text()).lower().strip() in f] ).replace(',', '<br>') + '<hr><h3> Search PyPI Python files: </h3>' + # wraped pypi query REMOTE search str(pypi_fls).replace(',', '<br>') + '<hr>Auto-Proxy:ON,DoNotTrack:ON') # print(s_out) try: call('notify-send fileXplorer Searching...', shell=True) except: pass self.srch.clear() self.textBrowser.setGeometry(self.dock.geometry()) self.textBrowser.setHtml(s_out) self.textBrowser.show() tmr = QTimer(self.fileView) tmr.timeout.connect(self.textBrowser.hide) tmr.start(20000) def iconChooser(self): ' Choose a Icon and copy it to clipboard ' # from .std_icon_naming import std_icon_naming as a # prv = QDialog(self.dock) prv.setWindowFlags(Qt.FramelessWindowHint) prv.setAutoFillBackground(True) prv.setGeometry(self.fileView.geometry()) table = QTableWidget(prv) table.setColumnCount(1) table.setRowCount(len(a)) table.verticalHeader().setVisible(True) table.horizontalHeader().setVisible(False) table.setShowGrid(True) table.setIconSize(QSize(128, 128)) for index, icon in enumerate(a): item = QTableWidgetItem(QIcon.fromTheme(icon), '') # item.setData(Qt.UserRole, '') item.setToolTip(icon) table.setItem(index, 0, item) table.clicked.connect(lambda: QApplication.clipboard().setText( 'QtGui.QIcon.fromTheme("{}")'.format(table.currentItem().toolTip()))) table.doubleClicked.connect(prv.close) table.resizeColumnsToContents() table.resizeRowsToContents() QLabel('<h3> <br> 1 Click Copy, 2 Clicks Close </h3>', table) table.resize(prv.size()) prv.exec_() def runfile(self, index): ' run the choosed file ' s = str(file(self.model.filePath(index), 'r').read().strip()) f = str(self.model.filePath(index)) # ctime is NOT crossplatform,metadata change on *nix,creation on Window # http://docs.python.org/library/os.path.html#os.path.getctime m = ''.join((f, N, str(path.getsize(f) / 1024), ' Kilobytes', N, str(len(file(f, 'r').readlines())), ' Lines', N, str(len(s.replace(N, ''))), ' Characters', N, str(len([a for a in sub('[^a-zA-Z0-9 ]', '', s).split(' ') if a != ''])), ' Words', N, str(len([a for a in s if a in punctuation])), ' Punctuation', N, oct(stat(f).st_mode)[-3:], ' Permissions', N, time.ctime(path.getatime(f)), ' Accessed', N, time.ctime(path.getmtime(f)), ' Modified', N, 'Owner: ', str(self.model.fileInfo(index).owner()), N, 'Is Writable: ', str(self.model.fileInfo(index).isWritable()), N, 'Is Executable: ', str(self.model.fileInfo(index).isExecutable()), N, 'Is Hidden: ', str(self.model.fileInfo(index).isHidden()), N, 'Is SymLink: ', str(self.model.fileInfo(index).isSymLink()), N, 'File Extension: ', str(self.model.fileInfo(index).suffix()) )) #print(m) self.preview.setToolTip(m) self.preview.setText(s) self.preview.resize(self.preview.size().width(), self.dock.size().height()) self.process.start('xdg-open {}'.format(f)) if not self.process.waitForStarted(): print((" ERROR: Process {} Failed ! ".format(str(f)))) return