|
|
#-*- coding: utf-8 -*-
|
|
|
|
|
|
# Copyright 2012-2013 Calculate Ltd. http://www.calculate-linux.org
|
|
|
#
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
# You may obtain a copy of the License at
|
|
|
#
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
#
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
# See the License for the specific language governing permissions and
|
|
|
# limitations under the License.
|
|
|
|
|
|
import sys
|
|
|
import progressbar
|
|
|
import signal
|
|
|
from os import environ
|
|
|
from multiprocessing import Process,Queue
|
|
|
|
|
|
try:
|
|
|
from PySide import QtCore, QtGui, QtNetwork
|
|
|
from PySide.QtGui import QProgressBar
|
|
|
class ControlledProgressDialog(QtGui.QProgressDialog):
|
|
|
"""
|
|
|
QProgressDialog controlled by pipe
|
|
|
"""
|
|
|
def __init__(self,inQueue,outQueue,*args,**kwargs):
|
|
|
QtGui.QProgressDialog.__init__(self,*args,**kwargs)
|
|
|
self.progress = QProgressBar(self)
|
|
|
self.progress.setFormat("%p%")
|
|
|
self.setBar(self.progress)
|
|
|
self.inQueue = inQueue
|
|
|
self.outQueue = outQueue
|
|
|
self.timer = QtCore.QTimer(self)
|
|
|
self.timer.timeout.connect(self.dispatcher)
|
|
|
self.timer.start(50)
|
|
|
self.center()
|
|
|
|
|
|
def setTextVisible(self,visible):
|
|
|
self.progress.setTextVisible(visible)
|
|
|
|
|
|
def center(self):
|
|
|
screen = QtGui.QDesktopWidget().screenGeometry()
|
|
|
size = self.geometry()
|
|
|
self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)
|
|
|
|
|
|
@QtCore.Slot()
|
|
|
def dispatcher(self):
|
|
|
"""
|
|
|
Dispatcher called by 50ms
|
|
|
"""
|
|
|
while not self.inQueue.empty():
|
|
|
cmd,args,ret = self.inQueue.get()
|
|
|
if cmd == "quit":
|
|
|
self.timer.stop()
|
|
|
self.close()
|
|
|
else:
|
|
|
res = getattr(self,cmd)(*args)
|
|
|
if ret:
|
|
|
self.outQueue.put(res)
|
|
|
self.center()
|
|
|
|
|
|
def sigint_handler(*args):
|
|
|
pass
|
|
|
|
|
|
class ClMessageBox:
|
|
|
"""
|
|
|
ProgressDialog in other process
|
|
|
"""
|
|
|
def runProgress(self,message,typemes="warning"):
|
|
|
signal.signal(signal.SIGINT, sigint_handler)
|
|
|
app = QtGui.QApplication(sys.argv)
|
|
|
getattr(QtGui.QMessageBox,typemes)(None,"",message,
|
|
|
QtGui.QMessageBox.StandardButton.Close,
|
|
|
QtGui.QMessageBox.StandardButton.Close)
|
|
|
|
|
|
def critical(self,message):
|
|
|
self.proc = Process(target=self.runProgress,
|
|
|
args=(message,"critical"))
|
|
|
self.proc.start()
|
|
|
self.proc.join()
|
|
|
|
|
|
def warning(self,message):
|
|
|
self.proc = Process(target=self.runProgress,
|
|
|
args=(message,"warning"))
|
|
|
self.proc.start()
|
|
|
self.proc.join()
|
|
|
|
|
|
class ClProgressDialog:
|
|
|
"""
|
|
|
ProgressDialog in other process
|
|
|
"""
|
|
|
homeDir = '/root'
|
|
|
|
|
|
def runProgress(self,inQueue,outQueue):
|
|
|
signal.signal(signal.SIGINT, sigint_handler)
|
|
|
environ['HOME']=self.homeDir
|
|
|
app = QtGui.QApplication(sys.argv)
|
|
|
progressDialog = ControlledProgressDialog(inQueue,outQueue)
|
|
|
progressDialog.exec_()
|
|
|
|
|
|
methods = ["autoClose","autoReset","colorCount","depth",
|
|
|
"maximum","minimum","minimumDuration",
|
|
|
"setLabelText","setMaximum","setMinimum",
|
|
|
"setMinimumDuration","setRange","setValue",
|
|
|
"setAutoClose","setAutoReset","setWindowTitle",
|
|
|
"setCancelButton","value","setTextVisible",
|
|
|
"adjustSize"]
|
|
|
|
|
|
def __init__(self):
|
|
|
self.outQueue = Queue()
|
|
|
self.finished = False
|
|
|
self.inQueue = Queue()
|
|
|
Process(target=self.runProgress,
|
|
|
args=(self.outQueue,self.inQueue)).start()
|
|
|
for method in self.methods:
|
|
|
setattr(self,method,self.proxyCall(method))
|
|
|
|
|
|
def proxyCall(self,method):
|
|
|
def wrapper(*args,**kwargs):
|
|
|
needRet = kwargs.get('needRet',False)
|
|
|
self.outQueue.put((method,args,needRet))
|
|
|
if needRet:
|
|
|
return self.inQueue.get()
|
|
|
return None
|
|
|
return wrapper
|
|
|
|
|
|
def quit(self):
|
|
|
self.outQueue.put(("quit",(),False))
|
|
|
self.finished = True
|
|
|
self.outQueue.close()
|
|
|
self.inQueue.close()
|
|
|
|
|
|
def finish(self):
|
|
|
self.quit()
|
|
|
|
|
|
def update(self, value):
|
|
|
self.setMaximum(100)
|
|
|
self.setTextVisible(True)
|
|
|
self.setValue(min(value, 99))
|
|
|
|
|
|
|
|
|
except:
|
|
|
ControlledProgressDialog = None
|
|
|
ClProgressDialog = None
|
|
|
ClMessageBox = None
|
|
|
|
|
|
|
|
|
class DoubleMarkerBar(progressbar.Bar):
|
|
|
"""
|
|
|
Прогресс с двойным маркером
|
|
|
"""
|
|
|
def update(self, pbar, width):
|
|
|
left, marker, right = (progressbar.format_updatable(i, pbar) for i in
|
|
|
(self.left, self.marker, self.right))
|
|
|
|
|
|
width -= len(left) + len(right)
|
|
|
# Marker must *always* have length of 2
|
|
|
count = int(float(pbar.currval) / pbar.maxval * width)
|
|
|
marker = marker[:1]*(count-1)+(marker[1:] if count>0 else "")
|
|
|
|
|
|
if self.fill_left:
|
|
|
return '%s%s%s' % (left, marker.ljust(width, self.fill), right)
|
|
|
else:
|
|
|
return '%s%s%s' % (left, marker.rjust(width, self.fill), right)
|
|
|
|
|
|
|
|
|
class StubProgressBar:
|
|
|
def update(self, percents):
|
|
|
pass
|
|
|
|
|
|
def finish(self):
|
|
|
pass
|
|
|
|
|
|
|
|
|
class StubMessageBox:
|
|
|
def critical(self, message):
|
|
|
pass
|
|
|
|
|
|
def warning(self, message):
|
|
|
pass
|
|
|
|
|
|
|
|
|
def get_progress_bar(bartype="text", title=""):
|
|
|
"""
|
|
|
Получить объект прогресс бар
|
|
|
"""
|
|
|
if bartype == "text":
|
|
|
return progressbar.ProgressBar(
|
|
|
maxval=100,
|
|
|
widgets=[DoubleMarkerBar(left="[", right="]", marker="=>"), " ",
|
|
|
progressbar.Percentage()," ",
|
|
|
progressbar.Timer(
|
|
|
format="Time:%s")]).start()
|
|
|
elif bartype == "gui" and ClProgressDialog:
|
|
|
pbar = ClProgressDialog()
|
|
|
pbar.setCancelButton(None)
|
|
|
pbar.adjustSize()
|
|
|
pbar.setWindowTitle(title.decode('utf-8'))
|
|
|
pbar.setAutoClose(False)
|
|
|
pbar.setAutoReset(False)
|
|
|
pbar.setMaximum(0)
|
|
|
pbar.setLabelText(title.decode('utf-8'))
|
|
|
pbar.setTextVisible(False)
|
|
|
return pbar
|
|
|
return StubProgressBar()
|
|
|
|
|
|
def get_message_box():
|
|
|
"""
|
|
|
Получить message box
|
|
|
"""
|
|
|
if ClMessageBox:
|
|
|
return ClMessageBox()
|
|
|
else:
|
|
|
return StubMessageBox()
|