class SummarySection(QTabWidget):
  """
  Represents the summary section.
  Takes reply data from main ui and updates it's tabs
  Keeps track of cumulative summary data.
  """
  def __init__(self, parent=None):
    super(SummarySection, self).__init__(parent)
    self.text_edit_summary = QTextEdit()
    self.text_edit_summary.setReadOnly(True)
    self.addTab(self.text_edit_summary, "Output")
    self.ball_grid = BallGrid(30, 30, 2)
    self.addTab(self.ball_grid, "Led View")
    self.tab_summary = SummaryTab()
    self.addTab(self.tab_summary, "Summary")
    #some private fields, keep track of accumulated summary data
    self.current_ip = 0 #we take reply data for ips in order
    self.sent_packets = 0
    self.received_packets = 0
    self.average_delay = 0
    
  def setIPs(self, ips):
    #this indicates the start of a new ping, could be treated
    #as a pingStarted signal
    self.current_ip = 0
    self.sent_packets = 0
    self.received_packets = 0
    self.average_delay = 0
    self.text_edit_summary.clear()
    self.ball_grid.layoutForIps(ips)
    self.tab_summary.zeroOut()
  
  def takeReplyData(self, replyData, sentPackets): #sent packets is passed in as extra
    """
    Update the output text area with the replyData string representation
    Set proper widget states on the BallGrid
    Calculate summaries cumulatively and set them for display on the summary tab 
    """
    self.text_edit_summary.append(str(replyData))
    packets_lost = replyData.packets_lost
    if packets_lost:
      self.ball_grid.setStateAt(self.current_ip, BallWidget.UNREACHABLE)
    else:
      self.ball_grid.setStateAt(self.current_ip, BallWidget.REACHABLE)
    self.current_ip += 1
    self.sent_packets += sentPackets 
    self.received_packets = self.sent_packets - replyData.packets_lost
    self.average_delay += (replyData.rtt / self.current_ip) #the current_ip reflects the overall number of replies
    summary_data = SummaryData(self.sent_packets, self.received_packets, self.average_delay)
    self.tab_summary.setSummaryData(summary_data)
    
  def pingingStoppedHandler(self):
    self.ball_grid.pingingCancelledHandler()
Beispiel #2
0
class Console():
    def __init__(self, targetLayoutContainer):
        self.textarea = QTextEdit()
        self.commits = QListWidget()
        
        self.commits.addAction(QAction('Rollback to this revision', self.commits, triggered=self.rollback))
        self.commits.setContextMenuPolicy(Qt.ActionsContextMenu)
        
        self.widget = QTabWidget()
        self.widget.addTab(self.textarea, 'Log')
        self.widget.addTab(self.commits, 'Commits')
        
        targetLayoutContainer.addWidget(self.widget)
        
    def color(self, module, function, color,  *args):
        print module, function, args
        
        prettyString = '<font color="' + color + '"><b>', module, '</b><i>::', function, '</i> --> ', ''.join(args), '</font>'
        self.textarea.append(''.join(prettyString))    
        
    def info(self, module, function, *args):
        print module, function, args
        
        prettyString = '<font color="black"><b>', module, '</b><i>::', function, '</i> --> ', ''.join(args), '</font>'
        self.textarea.append(''.join(prettyString))
        
    def error(self, module, function, *args):
        print module, function, args
        
        prettyString = '<font color="red"><b>', module, '</b><i>::', function, '</i> --> ', ''.join(args), '</font>'
        self.textarea.append(''.join(prettyString))
        
    def warn(self, module, function, *args):
        print module, function, args
        
        prettyString = '<font color="#BE9900"><b>', module, '</b><i>::', function, '</i> --> ', ''.join(args), '</font>'
        self.textarea.append(''.join(prettyString))
        
    def set_commits(self, commits):
        self.commits.clear()
        
        for commit in commits:
            self.commits.addItem(commit)
            
    def clear(self):
        self.textarea.clear()
        
    def rollback(self):
        targetCommit = self.commits.currentItem().text().split(' ')[0]
        if QMessageBox.warning(None, 'Rollback to commit?', 'All commits after ' + targetCommit + ' will be lost, proceed?', QMessageBox.Yes, QMessageBox.No) == QMessageBox.Yes:
            rollback(targetCommit)
Beispiel #3
0
class LoggingArea(QWidget):
    def __init__(self, parent=None):
        super(LoggingArea, self).__init__()

        self.layout = QVBoxLayout(self)

        self.hbox_buttons_top = QHBoxLayout(self)
        self.button_start = QPushButton('Start Logging', self)
        self.button_start.clicked.connect(parent._start_logging)
        self.hbox_buttons_top.addWidget(self.button_start)
        self.button_stop = QPushButton('Stop Logging', self)
        self.button_stop.clicked.connect(parent._stop_logging)
        self.hbox_buttons_top.addWidget(self.button_stop)
        self.layout.addLayout(self.hbox_buttons_top)

        self.te_logging = QTextEdit(self)
        self.layout.addWidget(self.te_logging)

        self.hbox_buttons_bottom = QHBoxLayout(self)
        self.button_clear = QPushButton('Clear Data', self)
        self.button_clear.clicked.connect(self._clear_data)
        self.hbox_buttons_bottom.addWidget(self.button_clear)
        self.button_clipboard = QPushButton('Copy to Clipboard', self)
        self.button_clipboard.clicked.connect(self._copy_to_cliboard)
        self.hbox_buttons_bottom.addWidget(self.button_clipboard)
        # self.button_file = QPushButton('Save to CSV', self)
        # self.button_file.clicked.connect(self._save_to_csv)
        # # self.button_file.setEnabled(False)
        # self.hbox_buttons_bottom.addWidget(self.button_file)
        self.layout.addLayout(self.hbox_buttons_bottom)

        self.setLayout(self.layout)

    def _clear_data(self):
        self.te_logging.clear()

    def _copy_to_cliboard(self):
        self.te_logging.selectAll()
        self.te_logging.copy()

    def _save_to_csv(self):
        results = self.te_logging.toPlainText()

        print results
Beispiel #4
0
class Prozor(QWidget):
    def __init__(self,element):
        #kreiramo prozor
        QWidget.__init__(self)
        self.element = element
        #iskljucujemo polja za uvecanje i minimizaciju
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowMaximizeButtonHint & ~Qt.WindowMinimizeButtonHint)
        #Podesavamo naslov
        self.setWindowTitle(self.element.ime)
        self.focusWidget()
        #editor teksta
        self.textEditor = QTextEdit()
        self.textEditor.setText(self.element.data)
        #dodajemo dugmad za primenu i odbacivanje promena
        #i povezujemo ih sa odgovarajucim funkcijama
        self.dugmeOk = QPushButton("Potvrdi")
        self.dugmeOtkazi = QPushButton("Otkazi")
        self.connect(self.dugmeOk,SIGNAL('clicked()'),self,SLOT('podesi()'))
        self.connect(self.dugmeOtkazi,SIGNAL('clicked()'),self,SLOT('zatvori()'))
        #formiramo raspored
        raspored = QFormLayout()
        raspored.addRow(self.textEditor)
        raspored.addRow(self.dugmeOtkazi,self.dugmeOk)
        self.setLayout(raspored)
        
    def zatvori(self):
        '''
            Funkcija za dugme otkazi promene, vraca parametre liste na trenutno stanje aplikacije
        '''
        self.textEditor.clear()
        self.textEditor.setText(self.element.data)
        self.hide()
        
    def podesi(self):
        '''
            Funkcija za dugme potvrdi promene, poziva akcije za izmenu jezika i izgleda
        '''
        self.element.data = self.textEditor.toPlainText()
        self.hide()
        
    def closeEvent(self, event):
        self.zatvori()
class CardBordAIApp(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("CardBord AI Demo ver0.10")
        self.operator = Operator()

        self.setupUi()

        self.operator.speach.connect(self.speak_ai)

        self.init()

    def setupUi(self):
        self.mainlayout = QVBoxLayout(self)

        self.title = QLabel("CardBord Operator", self)
        self.mainlayout.addWidget(self.title)

        self.user_txtarea = QTextEdit(self)
        self.ai_txtarea = QTextEdit(self)

        self.users_edit_title = QLabel("質問に答えてください")
        self.users_edit = QLineEdit("", self)

        self.txtarea_layout = QHBoxLayout()

        self.txtarea_layout.addWidget(self.user_txtarea)
        self.txtarea_layout.addWidget(self.ai_txtarea)

        self.mainlayout.addLayout(self.txtarea_layout)
        self.mainlayout.addWidget(self.users_edit_title)
        self.mainlayout.addWidget(self.users_edit)

        self.send_btn = QPushButton("send", self)
        self.send_btn.setObjectName("send_btn")
        self.mainlayout.addWidget(self.send_btn)

        QMetaObject.connectSlotsByName(self)

    def init(self):
        # Talkエリアの初期化
        self.user_txtarea.clear()
        self.ai_txtarea.clear()
        # オペレータ初期化、初期ワード取得
        self.operator.init()

    @Slot()
    def on_send_btn_clicked(self):
        # UI処理
        user_word = self.users_edit.text()
        if user_word == "":
            return None
        self.users_edit.clear()
        self.user_txtarea.append(user_word)

        # サーバー(エンジン)へユーザワードを送信
        self.operator.send(user_word)

    @Slot()
    def speak_ai(self, word):
        # AIのトークを表示
        # ディレイを使ってテンポを整える
        def wrapper():
            self.ai_txtarea.append(word)

        QTimer.singleShot(TALK_DELAY, wrapper)
Beispiel #6
0
class MainWindow(QMainWindow):
    def __init__(self):

        # QMainWindow.__init__(self)
        super().__init__()      # use super() to avoid explicit dependency on the base class name
                                # Note: must not pass the self reference to __init__ in this case!
        self.resize(800, 600)

        # Create the main content widget
        mainWidget = QWidget(self)
        self.setCentralWidget(mainWidget)

        # Create a text component at the top area of the main widget
        self.output = QTextEdit(mainWidget)
        self.output.setReadOnly(True)
        self.output.setLineWrapMode(QTextEdit.NoWrap);

        # set the font
        font = self.output.font()
        font.setFamily("Courier")
        font.setPointSize(10)
        self.output.setFont(font)

        # Set the background color
        # self.output.setTextBackgroundColor(Qt.red) # Only sets the background color for the text itself, not for the whole widget
        pal = self.output.palette()
        pal.setColor(QPalette.Base, Qt.black)
        self.output.setPalette(pal)

        mainLayout = QVBoxLayout(mainWidget)
        mainLayout.addWidget(self.output)

        # Create buttons in a grid layout below the top area
        buttonWidget = QWidget(mainWidget)
        self.buttonLayout = QGridLayout(buttonWidget)
        mainLayout.addWidget(buttonWidget)

        # Add some buttons to execute python code
        self.row = 0
        self.column = 0
        self.addButton("Clear console", lambda : self.output.clear())
        self.newRow()

        # Add buttons for all the examples - attention: do not make "examples"
        # a local variable - otherwise, the Examples object would be destroyed
        # at the end of __init__ !!!
        self.examples = samplePackage.SampleModule.Examples(self)
        for example in self.examples.getExamples():
            if example is None:
                self.newRow()
            else:
                self.addButton(example.label, example.function)

        # In a Python program, sys.excepthook is called just before the program exits.
        # So we can catch all fatal, uncaught exceptions and log them.
        # NOTE: we must be sure not to set the excepthook BEFORE we an actually
        # log something!! 
        sys.excepthook = self.logException

        self.writelnColor(Qt.magenta, 
                          "Python version: {0}.{1}.{2} ({3})".format(
                              sys.version_info[0], 
                              sys.version_info[1], 
                              sys.version_info[2], 
                              sys.version_info[3]))
        self.writelnColor(Qt.magenta, 
                          "Qt version    : {0}".format(qVersion()))


    def logException(self, exctype, value, tb):
        self.writelnColor(Qt.red, 
                          ("\nFATAL ERROR: Uncaught exception\n"
                           "  {}: {}\n"
                           "{}\n".format(exctype.__name__, value, ''.join(traceback.format_tb(tb)))) )


    def addButton(self, label, function):
        theButton = QPushButton(label)
        theButton.clicked.connect(function)
        self.buttonLayout.addWidget(theButton, self.row, self.column)
        self.column += 1


    def newRow(self):
        self.row += 1
        self.column = 0


    def writeColor(self, color, *text):
        theText =  ' '.join(map(str, text))
        self.output.setTextColor(color)

        # Note: append() adds a new paragraph!
        #self.output.append(theText)
        self.output.textCursor().movePosition(QTextCursor.End)
        self.output.insertPlainText(theText)

        # scroll console window to bottom        
        sb = self.output.verticalScrollBar()
        sb.setValue(sb.maximum())


    def write(self, *text):
        self.writeColor(Qt.green, *text)


    def writelnColor(self, color, *text):
        self.writeColor(color, *text)
        self.write('\n')


    def writeln(self, *text):
        self.writelnColor(Qt.green, *text)
Beispiel #7
0
class MainWindow(QMainWindow):
    windows = []

    def __init__(self):
        super(MainWindow, self).__init__()

        # Store ourself.
        self.windows.append(self)

        # State!
        self.current_file = None

        # Editor!
        self.editor = QTextEdit()
        self.setCentralWidget(self.editor)

        # Style the editor
        #style.apply_stylesheet(self.editor, 'editor.qss')

        # Menus and Stuff!
        self.init_actions()
        self.init_menus()
        self.init_toolbars()
        self.init_statusbar()

        # Settings!
        self.init_settings()

        # Icons!
        self.reload_icons()
        #style.style_reloaded.connect(self.reload_icons)

        # Fancy!
        #style.enable_aero(self)
        self.update_title()

        # Now, for some plugins.
#        plugins.run_signal('new_window', self)

##### Action Icons! #######################################################

    def reload_icons(self):
        #self.setWindowIcon(style.icon('application'))
        pass
#         a = self.actions
#         for key in a.keys():
#             a[key].setIcon(style.icon(key.lower()))

##### Actions! ############################################################

    def init_actions(self):
        self.actions = a = {}

        ##### File Menu #######################################################

        a['document-new'] = QAction("&New",
                                    self,
                                    shortcut=QKeySequence.New,
                                    statusTip="Create a new file.",
                                    triggered=self.action_new)

        a['document-open'] = QAction("&Open",
                                     self,
                                     shortcut=QKeySequence.Open,
                                     statusTip="Open an existing file.",
                                     triggered=self.action_open)

        a['document-save'] = QAction("&Save",
                                     self,
                                     shortcut=QKeySequence.Save,
                                     statusTip="Save the document to disk.",
                                     triggered=self.action_save)

        a['application-exit'] = QAction("E&xit",
                                        self,
                                        statusTip="Exit the application.",
                                        triggered=self.close)

        ##### Edit Menu #######################################################

        a['edit-cut'] = QAction("Cu&t",
                                self,
                                shortcut=QKeySequence.Cut,
                                triggered=self.editor.cut)

        a['edit-copy'] = QAction("&Copy",
                                 self,
                                 shortcut=QKeySequence.Copy,
                                 triggered=self.editor.copy)

        a['edit-paste'] = QAction("&Paste",
                                  self,
                                  shortcut=QKeySequence.Paste,
                                  triggered=self.editor.paste)

        a['edit-cut'].setEnabled(False)
        a['edit-copy'].setEnabled(False)

        self.editor.copyAvailable.connect(a['edit-cut'].setEnabled)
        self.editor.copyAvailable.connect(a['edit-copy'].setEnabled)

        ##### Tool Menu #######################################################

        # This is the fun part.
        a['addon-manager'] = QAction("&Add-ons",
                                     self,
                                     shortcut="Ctrl+Shift+A",
                                     statusTip="Display the Add-ons manager.",
                                     triggered=addons.show)

#         a['view-refresh'] = QAction("&Reload Style", self,
#                                 shortcut="Ctrl+Shift+R",
#                                 statusTip="Reload the style.",
#                                 triggered=style.reload)

##### Menus! ##############################################################

    def init_menus(self):
        self.menuBar().clear()
        a = self.actions

        file = self.menuBar().addMenu("&File")
        file.addAction(a['document-new'])
        file.addAction(a['document-open'])
        file.addAction(a['document-save'])
        file.addSeparator()
        file.addAction(a['application-exit'])

        edit = self.menuBar().addMenu("&Edit")
        edit.addAction(a['edit-cut'])
        edit.addAction(a['edit-copy'])
        edit.addAction(a['edit-paste'])

        tools = self.menuBar().addMenu("&Tools")
        tools.addAction(a['addon-manager'])
        #tools.addAction(a['view-refresh'])

    ##### Explosions! #########################################################

    ##### Toolbars! ###########################################################

    def init_toolbars(self):
        a = self.actions

        file = self.addToolBar("File")
        file.setObjectName('filebar')
        file.addAction(a['document-new'])
        file.addAction(a['document-open'])
        file.addAction(a['document-save'])

        edit = self.addToolBar("Edit")
        edit.setObjectName('editbar')
        edit.addAction(a['edit-cut'])
        edit.addAction(a['edit-copy'])
        edit.addAction(a['edit-paste'])

        tools = self.addToolBar("Tools")
        tools.setObjectName('toolsbar')
        tools.addAction(a['addon-manager'])
        #tools.addAction(a['view-refresh'])

    ##### Statusbars! #########################################################

    def init_statusbar(self):
        self.statusBar().showMessage("Ready.")

    ##### Settings! ###########################################################

    def init_settings(self):
        self.restoreGeometry(profile.get("geometry"))
        self.restoreState(profile.get("state"))

    def save_settings(self):
        profile.set("geometry", self.saveGeometry())
        profile.set("state", self.saveState())

    ##### Actual Actions! #####################################################

    def update_title(self):
        if self.current_file:
            title = os.path.basename(self.current_file)
        else:
            title = "Untitled"
        self.setWindowTitle("%s - %s" %
                            (title, QApplication.instance().applicationName()))

    def action_new(self):
        if self.try_save():
            self.editor.clear()
            self.current_file = None
            self.update_title()

    def action_open(self):
        if self.try_save():
            fn = QFileDialog.getOpenFileName(self)[0]
            if not fn:
                return

            self.do_open(fn)

    def do_open(self, fn):
        with open(fn, 'r') as f:
            content = f.read()

        self.editor.setPlainText(content)
        self.current_file = fn
        self.update_title()

    def action_save(self):
        if not self.editor.document().isModified():
            return

        if not self.current_file:
            self.current_file = QFileDialog.getSaveFileName(self)[0]
            self.update_title()

        if not self.current_file:
            return

        with open(self.current_file, 'w') as f:
            f.write(self.editor.toPlainText())
        self.editor.document().setModified(False)

    ##### Adventure! ##########################################################

    def try_save(self):
        if self.editor.document().isModified():
            ret = QMessageBox.warning(
                self, "Blah Blah Blah",
                "That's an awfully nice modified document you've got there"
                ". It'd be a shame if anything... happened to it. Catch "
                "my drift?",
                QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)
            if ret == QMessageBox.Save:
                self.action_save()

            elif ret == QMessageBox.Cancel:
                return False

        return True

    def showRaise(self):
        """ Show and raise the window. """
        #         self.show()
        #         self.raise_()
        #         self.setFocus()
        self.activateWindow()
        if self.isMinimized():
            self.showNormal()

    def closeEvent(self, event):
        if self.try_save():
            self.save_settings()

            if self in self.windows:
                self.windows.remove(self)

#            plugins.run_signal('close_window', self)

            event.accept()
        else:
            event.ignore()
Beispiel #8
0
class TransferPanel(QWidget):
    '''
    Transfer Panel
    
    This Panel is the main dialog box for the Dive Computer Transfer GUI
    '''
    def __init__(self, parent=None):
        super(TransferPanel, self).__init__(parent)
        
        self._logbook = None
        self._logbookName = 'None'
        self._logbookPath = None
        
        self._createLayout()
        
        self._readSettings()
        self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName)
        
    def _createLayout(self):
        'Create the Widget Layout'
        
        self._txtLogbook = QLineEdit()
        self._txtLogbook.setReadOnly(True)
        self._lblLogbook = QLabel(self.tr('&Logbook File:'))
        self._lblLogbook.setBuddy(self._txtLogbook)
        self._btnBrowse = QPushButton('...')
        self._btnBrowse.clicked.connect(self._btnBrowseClicked)
        self._btnBrowse.setStyleSheet('QPushButton { min-width: 24px; max-width: 24px; }')
        self._btnBrowse.setToolTip(self.tr('Browse for a Logbook'))
        
        self._cbxComputer = QComboBox()
        self._lblComputer = QLabel(self.tr('Dive &Computer:'))
        self._lblComputer.setBuddy(self._cbxComputer)
        self._btnAddComputer = QPushButton(QPixmap(':/icons/list-add.png'), self.tr(''))
        self._btnAddComputer.setStyleSheet('QPushButton { min-width: 24px; min-height: 24; max-width: 24px; max-height: 24; }')
        self._btnAddComputer.clicked.connect(self._btnAddComputerClicked)
        self._btnRemoveComputer = QPushButton(QPixmap(':/icons/list-remove.png'), self.tr(''))
        self._btnRemoveComputer.setStyleSheet('QPushButton { min-width: 24px; min-height: 24; max-width: 24px; max-height: 24; }')
        self._btnRemoveComputer.clicked.connect(self._btnRemoveComputerClicked)
        
        hbox = QHBoxLayout()
        hbox.addWidget(self._btnAddComputer)
        hbox.addWidget(self._btnRemoveComputer)
        
        gbox = QGridLayout()
        gbox.addWidget(self._lblLogbook, 0, 0)
        gbox.addWidget(self._txtLogbook, 0, 1)
        gbox.addWidget(self._btnBrowse, 0, 2)
        gbox.addWidget(self._lblComputer, 1, 0)
        gbox.addWidget(self._cbxComputer, 1, 1)
        gbox.addLayout(hbox, 1, 2)
        gbox.setColumnStretch(1, 1)
        
        self._pbTransfer = QProgressBar()
        self._pbTransfer.reset()
        self._txtStatus = QTextEdit()
        self._txtStatus.setReadOnly(True)
        
        self._btnTransfer = QPushButton(self.tr('&Transfer Dives'))
        self._btnTransfer.clicked.connect(self._btnTransferClicked)
        
        self._btnExit = QPushButton(self.tr('E&xit'))
        self._btnExit.clicked.connect(self.close)
        
        hbox = QHBoxLayout()
        hbox.addWidget(self._btnTransfer)
        hbox.addStretch()
        hbox.addWidget(self._btnExit)
        
        vbox = QVBoxLayout()
        vbox.addLayout(gbox)
        vbox.addWidget(self._pbTransfer)
        vbox.addWidget(self._txtStatus)
        vbox.addLayout(hbox)
        
        self.setLayout(vbox)
        
    def _closeLogbook(self):
        'Close the current Logbook'
        if self._logbook is None:
            return
        
        self._logbook = None
        self._logbookName = 'None'
        self._logbookPath = None
        
        self._txtLogbook.clear()
        self._cbxComputer.setModel(None)
        
        self._writeSettings()
        self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName)
        
    def _openLogbook(self, path):
        'Open an existing Logbook'
        if self._logbook is not None:
            self._closeLogbook()
            
        if not os.path.exists(path):
            QMessageBox.critical(self, self.tr('Missing Logbook'), 
                self.tr('Logbook File "%s" does not exist.') % path)
            return
        
        #TODO: Handle a Schema Upgrade in a user-friendly manner
        self._logbook = Logbook(path, auto_update=False)
        self._logbookName = os.path.basename(path)
        self._logbookPath = path
        
        self._txtLogbook.setText(self._logbookPath)
        self._cbxComputer.setModel(DiveComputersModel(self._logbook))
        
        self._writeSettings()
        self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName)
        
    def _readSettings(self):
        'Read main window settings from the configuration'
        settings = QSettings()
        settings.beginGroup('MainWindow')
        max = settings.value('max')
        size = settings.value('size')
        pos = settings.value('pos')
        file = settings.value('file')
        settings.endGroup()
        
        # Size and Position the Main Window
        if size is not None:
            self.resize(size)
        if pos is not None:
            self.move(pos)
            
        # HAX because QVariant is not exposed in PySide and the default
        # coercion to string is just stupid
        if max is not None and (max == 'true'):
            self.showMaximized()
        
        # Open the Logbook
        if file is not None:
            self._openLogbook(file)
        
    def _writeSettings(self):
        'Write settings to the configuration'
        settings = QSettings()
        settings.beginGroup('MainWindow')
        settings.setValue('pos', self.pos())
        settings.setValue('size', self.size())
        settings.setValue('max', self.isMaximized())
        settings.setValue('file', self._logbookPath)
        settings.endGroup()
        
    def closeEvent(self, e):
        'Intercept an OnClose event'
        self._writeSettings()
        e.accept()
        
    #--------------------------------------------------------------------------
    # Slots
    
    @QtCore.Slot()
    def _btnAddComputerClicked(self):
        'Add a Dive Computer'
        dc = AddDiveComputerWizard.RunWizard(self)
        
        if dc is not None:
            self._logbook.session.add(dc)
            self._logbook.session.commit()
            self._cbxComputer.model().reload()
            self._cbxComputer.setCurrentIndex(self._cbxComputer.findText(dc.name))
    
    @QtCore.Slot()
    def _btnRemoveComputerClicked(self):
        'Remove a Dive Computer'
        idx = self._cbxComputer.currentIndex()
        dc = self._cbxComputer.itemData(idx, Qt.UserRole+0)
        if QMessageBox.question(self, self.tr('Delete Dive Computer?'), 
                    self.tr('Are you sure you want to delete "%s"?') % dc.name,
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) == QMessageBox.Yes:
            self._logbook.session.delete(dc)
            self._logbook.session.commit()
            self._cbxComputer.model().reload()
    
    @QtCore.Slot()
    def _btnBrowseClicked(self):
        'Browse for a Logbook File'
        if self._logbook is not None:
            dir = os.path.dirname(self._logbookPath)
        else:
            dir = os.path.expanduser('~')
        
        fn = QFileDialog.getOpenFileName(self,
            caption=self.tr('Select a Logbook file'), dir=dir,
            filter='Logbook Files (*.lbk);;All Files(*.*)')[0]    
        if fn == '':
            return
        if not os.path.exists(fn):
            if QMessageBox.question(self, self.tr('Create new Logbook?'), 
                    self.tr('Logbook "%s" does not exist. Would you like to create it?') % os.path.basename(fn),
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) != QMessageBox.Yes:
                return
            Logbook.Create(fn)
        self._openLogbook(fn)
        
    @QtCore.Slot()
    def _btnTransferClicked(self):
        'Transfer Dives'
        idx = self._cbxComputer.currentIndex()
        dc = self._cbxComputer.itemData(idx, Qt.UserRole+0)
        
        if self._logbook.session.dirty:
            print "Flushing dirty session"
            self._logbook.rollback()
        
        self._txtLogbook.setEnabled(False)
        self._btnBrowse.setEnabled(False)
        self._cbxComputer.setEnabled(False)
        self._btnAddComputer.setEnabled(False)
        self._btnRemoveComputer.setEnabled(False)
        self._btnTransfer.setEnabled(False)
        self._btnExit.setEnabled(False)
        
        self._txtStatus.clear()
        
        thread = QThread(self)
        
        #FIXME: ZOMG HAX: Garbage Collector will eat TransferWorker when moveToThread is called
        #NOTE: Qt.QueuedConnection is important...
        self.worker = None
        self.worker = TransferWorker(dc)
        thread.started.connect(self.worker.start, Qt.QueuedConnection)
        self.worker.moveToThread(thread)
        self.worker.finished.connect(self._transferFinished, Qt.QueuedConnection)
        self.worker.finished.connect(self.worker.deleteLater, Qt.QueuedConnection)
        self.worker.finished.connect(thread.deleteLater, Qt.QueuedConnection)
        self.worker.progress.connect(self._transferProgress, Qt.QueuedConnection)
        self.worker.started.connect(self._transferStart, Qt.QueuedConnection)
        self.worker.status.connect(self._transferStatus, Qt.QueuedConnection)
        
        thread.start()
        
    @QtCore.Slot(str)
    def _transferStatus(self, msg):
        'Transfer Status Message'
        self._txtStatus.append(msg)
        
    @QtCore.Slot(int)
    def _transferStart(self, nBytes):
        'Transfer Thread Stated'
        if nBytes > 0:
            self._pbTransfer.setMaximum(nBytes)
        else:
            self._pbTransfer.setMaximum(100)
        self._pbTransfer.reset()
        
    @QtCore.Slot(int)
    def _transferProgress(self, nTransferred):
        'Transfer Thread Progress Event'
        self._pbTransfer.setValue(nTransferred)
        
    @QtCore.Slot(models.Dive)
    def _transferParsed(self, dive):
        'Transfer Thread Parsed Dive'
        self._logbook.session.add(dive)
        
    @QtCore.Slot()
    def _transferFinished(self):
        'Transfer Thread Finished'
        self._logbook.session.commit()
        
        self._txtLogbook.setEnabled(True)
        self._btnBrowse.setEnabled(True)
        self._cbxComputer.setEnabled(True)
        self._btnAddComputer.setEnabled(True)
        self._btnRemoveComputer.setEnabled(True)
        self._btnTransfer.setEnabled(True)
        self._btnExit.setEnabled(True)
Beispiel #9
0
class MainWindow(QMainWindow):
    windows = []

    def __init__(self):
        super(MainWindow, self).__init__()

        # Store ourself.
        self.windows.append(self)

        # State!
        self.current_file = None

        # Editor!
        self.editor = QTextEdit()
        self.setCentralWidget(self.editor)

        # Style the editor
        style.apply_stylesheet(self.editor, 'editor.qss')
        
        # Menus and Stuff!
        self.init_actions()
        self.init_menus()
        self.init_toolbars()
        self.init_statusbar()

        # Settings!
        self.init_settings()

        # Icons!
        self.reload_icons()
        style.style_reloaded.connect(self.reload_icons)

        # Fancy!
        style.enable_aero(self)
        self.update_title()

        # Now, for some plugins.
        plugins.run_signal('new_window', self)

    ##### Action Icons! #######################################################

    def reload_icons(self):
        self.setWindowIcon(style.icon('application'))

        a = self.actions
        for key in a.keys():
            a[key].setIcon(style.icon(key.lower()))

    ##### Actions! ############################################################

    def init_actions(self):
        self.actions = a = {}

        ##### File Menu #######################################################

        a['document-new'] = QAction("&New", self, shortcut=QKeySequence.New,
                        statusTip="Create a new file.",
                        triggered=self.action_new)

        a['document-open'] = QAction("&Open", self, shortcut=QKeySequence.Open,
                        statusTip="Open an existing file.",
                        triggered=self.action_open)

        a['document-save'] = QAction("&Save", self, shortcut=QKeySequence.Save,
                        statusTip="Save the document to disk.",
                        triggered=self.action_save)

        a['application-exit'] = QAction("E&xit", self,
                        statusTip="Exit the application.",
                        triggered=self.close)

        ##### Edit Menu #######################################################

        a['edit-cut'] = QAction("Cu&t", self, shortcut=QKeySequence.Cut,
                        triggered=self.editor.cut)

        a['edit-copy'] = QAction("&Copy", self, shortcut=QKeySequence.Copy,
                        triggered=self.editor.copy)

        a['edit-paste'] = QAction("&Paste", self, shortcut=QKeySequence.Paste,
                        triggered=self.editor.paste)

        a['edit-cut'].setEnabled(False)
        a['edit-copy'].setEnabled(False)

        self.editor.copyAvailable.connect(a['edit-cut'].setEnabled)
        self.editor.copyAvailable.connect(a['edit-copy'].setEnabled)

        ##### Tool Menu #######################################################

        # This is the fun part.
        a['addon-manager'] = QAction("&Add-ons", self, shortcut="Ctrl+Shift+A",
                                statusTip="Display the Add-ons manager.",
                                triggered=addons.show)

        a['view-refresh'] = QAction("&Reload Style", self,
                                shortcut="Ctrl+Shift+R",
                                statusTip="Reload the style.",
                                triggered=style.reload)

    ##### Menus! ##############################################################

    def init_menus(self):
        self.menuBar().clear()
        a = self.actions

        file = self.menuBar().addMenu("&File")
        file.addAction(a['document-new'])
        file.addAction(a['document-open'])
        file.addAction(a['document-save'])
        file.addSeparator()
        file.addAction(a['application-exit'])

        edit = self.menuBar().addMenu("&Edit")
        edit.addAction(a['edit-cut'])
        edit.addAction(a['edit-copy'])
        edit.addAction(a['edit-paste'])

        tools = self.menuBar().addMenu("&Tools")
        tools.addAction(a['addon-manager'])
        tools.addAction(a['view-refresh'])

    ##### Explosions! #########################################################

    ##### Toolbars! ###########################################################

    def init_toolbars(self):
        a = self.actions

        file = self.addToolBar("File")
        file.setObjectName('filebar')
        file.addAction(a['document-new'])
        file.addAction(a['document-open'])
        file.addAction(a['document-save'])

        edit = self.addToolBar("Edit")
        edit.setObjectName('editbar')
        edit.addAction(a['edit-cut'])
        edit.addAction(a['edit-copy'])
        edit.addAction(a['edit-paste'])

        tools = self.addToolBar("Tools")
        tools.setObjectName('toolsbar')
        tools.addAction(a['addon-manager'])
        tools.addAction(a['view-refresh'])

    ##### Statusbars! #########################################################

    def init_statusbar(self):
        self.statusBar().showMessage("Ready.")

    ##### Settings! ###########################################################

    def init_settings(self):
        self.restoreGeometry(profile.get("geometry"))
        self.restoreState(profile.get("state"))

    def save_settings(self):
        profile.set("geometry", self.saveGeometry())
        profile.set("state", self.saveState())

    ##### Actual Actions! #####################################################

    def update_title(self):
        if self.current_file:
            title = os.path.basename(self.current_file)
        else:
            title = "Untitled"
        self.setWindowTitle("%s - %s" % (title,
                QApplication.instance().applicationName()))

    def action_new(self):
        if self.try_save():
            self.editor.clear()
            self.current_file = None
            self.update_title()

    def action_open(self):
        if self.try_save():
            fn = QFileDialog.getOpenFileName(self)[0]
            if not fn:
                return

            self.do_open(fn)

    def do_open(self, fn):
        with open(fn, 'r') as f:
            content = f.read()

        self.editor.setPlainText(content)
        self.current_file = fn
        self.update_title()

    def action_save(self):
        if not self.editor.document().isModified():
            return

        if not self.current_file:
            self.current_file = QFileDialog.getSaveFileName(self)[0]
            self.update_title()

        if not self.current_file:
            return

        with open(self.current_file, 'w') as f:
            f.write(self.editor.toPlainText())
        self.editor.document().setModified(False)

    ##### Adventure! ##########################################################

    def try_save(self):
        if self.editor.document().isModified():
            ret = QMessageBox.warning(self, "Blah Blah Blah",
                    "That's an awfully nice modified document you've got there"
                    ". It'd be a shame if anything... happened to it. Catch "
                    "my drift?",
                    QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel
                    )
            if ret == QMessageBox.Save:
                self.action_save()

            elif ret == QMessageBox.Cancel:
                return False

        return True

    def closeEvent(self, event):
        if self.try_save():
            self.save_settings()

            if self in self.windows:
                self.windows.remove(self)

            plugins.run_signal('close_window', self)

            event.accept()
        else:
            event.ignore()
Beispiel #10
0
class qNotebook(QVBoxLayout):
    def __init__(self):
        QVBoxLayout.__init__(self)
        self._teditor = QTextEdit()
        self._teditor.setMinimumWidth(500)
        self._teditor.setStyleSheet("font: 12pt \"Courier\";")
        button_layout = QHBoxLayout()
        self.addLayout(button_layout)
        self.clear_but = qmy_button(button_layout, self.clear_all, "clear")
        self.copy_but = qmy_button(button_layout, self._teditor.copy, "copy")
        qmy_button(button_layout, self._teditor.selectAll, "select all")
        qmy_button(button_layout, self._teditor.undo, "undo")
        qmy_button(button_layout, self._teditor.redo, "redo")
        search_button = qButtonWithArgumentsClass("search", self.search_for_text, {"search_text": ""})
        button_layout.addWidget(search_button)
        qmy_button(button_layout, self.save_as_html, "save notebook")
        
        self.addWidget(self._teditor)
        self._teditor.document().setUndoRedoEnabled(True)
        self.image_counter = 0
        self.image_dict = {}
        self.image_data_dict = {}
        
    def append_text(self, text):
        self._teditor.append(str(text))
        
    def search_for_text(self, search_text = " "):
        self._teditor.find(search_text)
        
    def clear_all(self):
        self._teditor.clear()
        self.image_dict = {}
        self.image_counter = 0
#        newdoc = QTextDocument()
#        self._teditor.setDocument(newdoc)
        
    def append_image(self, fig=None):
        #This assumes that an image is there waiting to be saved from matplotlib
        self.imgdata = StringIO.StringIO()
        if fig is None:
            pyplot.savefig(self.imgdata, transparent = False, format = img_format)
        else:
            fig.savefig(self.imgdata, transparent = False, format = img_format)
        self.abuffer = QBuffer()
        self.abuffer.open(QBuffer.ReadWrite)
        self.abuffer.write(self.imgdata.getvalue())
        self.abuffer.close()
        
        self.abuffer.open(QBuffer.ReadOnly)
        iReader = QImageReader(self.abuffer, img_format )
        the_image = iReader.read()
        # the_image = the_image0.scaledToWidth(figure_width)
        
        # save the image in a file
        imageFileName = "image" + str(self.image_counter) + "." + img_format
        self.image_data_dict[imageFileName] = self.imgdata
        
        self.image_counter +=1
        imageFormat = QTextImageFormat()
        imageFormat.setName(imageFileName)
        imageFormat.setWidth(image_width)
        self.image_dict[imageFileName] = the_image
        
        #insert the image in the text document
        text_doc = self._teditor.document()
        text_doc.addResource(QTextDocument.ImageResource, QUrl(imageFileName), the_image)
        cursor = self._teditor.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertImage(imageFormat)
        
    def add_image_data_resource(self, imgdata, imageFileName):
        
        self.abuffer = QBuffer()
        self.abuffer.open(QBuffer.ReadWrite)
        self.abuffer.write(imgdata.getvalue())
        self.abuffer.close()
        
        self.abuffer.open(QBuffer.ReadOnly)
        iReader = QImageReader(self.abuffer, img_format )
        the_image = iReader.read()
        # the_image = the_image0.scaledToWidth(figure_width)
        
        # save the image in a file
        # imageFileName = "image" + str(self.image_counter) + "." + img_format
        self.image_data_dict[imageFileName] = imgdata
        
        # self.image_counter +=1
        imageFormat = QTextImageFormat()
        imageFormat.setName(imageFileName)
        imageFormat.setWidth(image_width)
        self.image_dict[imageFileName] = the_image
        
        #insert the image in the text document
        text_doc = self._teditor.document()
        text_doc.addResource(QTextDocument.ImageResource, QUrl(imageFileName), the_image)
        
    
    def append_html_table_from_array(self, a, header_rows=0, precision = 3, caption = None, cmap = None):
        nrows = len(a)
        ncols = len(a[0])
        result_string = "<table border=\"1\" cellspacing=\"0\" cellpadding=\"2\">\n"
        if caption != None:
            result_string += "<caption>%s</caption>\n"  % caption
        r = 0
        while r < header_rows:
            result_string += "<tr>"
            for c in range(ncols):
                if a[r][c] != "":
                    # count following blank columns
                    count = 1
                    while ((c+count) < len(a[r])) and (a[r][c+count] == "") :
                        count += 1
                    val = a[r][c]
                    if (type(val) == numpy.float64) or (type(val) == float):  # @UndefinedVariable
                        if precision != 999:
                            val = round(val, precision)
                    if count > 1:
                        result_string +="<th colspan=%s>%s</th>"  % (count, val)
                    else:
                        result_string += "<th>%s</th>"  % val
            result_string +="</tr>\n"
            r += 1
        while r < nrows:
            result_string += "<tr>"
            for c in range(ncols):
                val = a[r][c]
                if (cmap == None):
                    fcolor = "#ffffff"
                elif (type(val) == int) or (type(val) == float) or (type(val) == numpy.float64):  # @UndefinedVariable
                    fcolor = cmap.color_from_val(val)
                else:
                    fcolor = "#ffffff"
      
                if (val != "") or (c == 0):
                    if (type(val) == numpy.float64) or (type(val) == float): # @UndefinedVariable
                        if precision != 999:
                            val = round(val, precision)
                    count = 1
                    while ((c+count) < len(a[r])) and (a[r][c+count] == "") :
                        count += 1
                    if count > 1:
                        result_string +="<td colspan=%s bgcolor=%s>%s</td>"  % (count, fcolor, val)
                    else:
                        result_string += "<td bgcolor=%s>%s</td>" % (fcolor, val)
            result_string +="</tr>\n"
            r += 1
        result_string += "</table>\n"
        self.append_text(result_string)
        
    def create_empty_string_array(self, rows, cols):
        table_array = []
        for r in range(rows): #@UnusedVariable
            the_row = []
            for c in range(cols): #@UnusedVariable
                the_row.append("")
            table_array.append(the_row)
        return table_array
    
    def recurse_on_dict_headers(self, sdict, r, c, sorted_headers = None):
        if ((type(sdict) != dict) and (type(sdict) != OrderedDict)):
            return c + 1
        else:
            if sorted_headers != None:
                sheaders = sorted_headers
            else:
                sheaders = sorted(sdict.keys())
            for k in sheaders:
                self.table_array[r][c] = k
                c = self.recurse_on_dict_headers(sdict[k], r + 1, c)
            return c
        
    def recurse_to_find_size(self, sdict, r, c):
        
        if ((type(sdict) != dict) and (type(sdict) != OrderedDict)):
            return r, c + 1
        else:
            rbiggest = r
            for k in sorted(sdict.keys()):
                rnew, c = self.recurse_to_find_size(sdict[k], r + 1, c)
                if rnew > rbiggest:
                    rbiggest = rnew
            return rbiggest, c
                
    def recurse_on_dict(self, sdict, r, c, sorted_headers = None):
        if ((type(sdict) != dict) and (type(sdict) != OrderedDict)):
            self.table_array[r][c] = sdict
            return c + 1
        else:
            if sorted_headers != None:
                sheaders = sorted_headers
            else:
                sheaders = sorted(sdict.keys())
            for k in sheaders:
                c = self.recurse_on_dict(sdict[k], r, c)
            return c

    def convert_structured_dicts_to_array(self, sdict, sorted_keys = None, sorted_headers = None):
        header_levels, ncols = self.recurse_to_find_size(sdict[sdict.keys()[0]], 0, 0)
        nrows = header_levels + len(sdict.keys())
        self.table_array = self.create_empty_string_array(nrows, ncols)
        self.recurse_on_dict_headers(sdict[sdict.keys()[0]], 0, 0, sorted_headers)
        if sorted_keys != None:
            key_list = sorted_keys
        else:
            key_list = sdict.keys()
        r = header_levels
        for entry in key_list:
            c = 0
            self.table_array[r][0] = entry
            self.recurse_on_dict(sdict[entry], r, c, sorted_headers = sorted_headers)
            r += 1
        return self.table_array
            
    def append_html_table_from_dicts(self, sdict, header_rows = 1, title = None, sorted_keys = None, precision = 3, cmap = None, sorted_headers = None):
        the_array = self.convert_structured_dicts_to_array(sdict, sorted_keys, sorted_headers = sorted_headers)
        self.append_html_table_from_array(the_array, header_rows, caption = title, precision = precision, cmap = cmap)
    
    def append_table(self, rows, cols, border_style = QTextFrameFormat.BorderStyle_Solid):
        tformat = QTextTableFormat()
        tformat.setBorderStyle(border_style)
        cursor= self._teditor.textCursor()
        cursor.movePosition(QTextCursor.End)
        table = cursor.insertTable(rows, cols, tformat)
        return table
    
    def fill_table_cell(self, row, col, table, text):
        cptr = table.cellAt(row, col).firstCursorPosition()
        cptr.insertText(text)
        
    def save_as_html(self):
        fname = QFileDialog.getSaveFileName()[0]
        fdirectoryname = os.path.dirname(fname)
        # fdirectoryname = QFileDialog.getExistingDirectory()
        # print fdirectoryname
        # fname = fdirectoryname + "/report.html"
        text_doc = self._teditor.document()
        f = open(fname, 'w')
        f.write(text_doc.toHtml())
        f.close()
        for imageFileName in self.image_dict.keys():
            full_image_path = fdirectoryname + "/" + imageFileName
            iWriter = QImageWriter(full_image_path, img_format)
            iWriter.write(self.image_dict[imageFileName])