def populateTree(self, projects): """populates tree with user projects """ logger.debug('TaskTreeModel.populateTree() is started') self.setColumnCount(4) self.setHorizontalHeaderLabels( ['Name', 'Type', 'Resources', 'Dependencies']) for project in projects: project_item = TaskItem(0, 4, task=project) project_item.parent = None project_item.setColumnCount(4) # Set Font my_font = project_item.font() my_font.setBold(True) project_item.setFont(my_font) # color with task status from anima import defaults project_item.setData( QtGui.QColor( *defaults.status_colors_by_id.get(project.status_id)), QtCore.Qt.BackgroundRole) # use black text project_item.setForeground(QtGui.QBrush(QtGui.QColor(0, 0, 0))) self.appendRow(project_item) logger.debug('TaskTreeModel.populateTree() is finished')
def ui_caller(app_in, executor, DialogClass, **kwargs): global app global mainDialog self_quit = False if QtGui.QApplication.instance() is None: if not app_in: try: app = QtGui.QApplication(sys.argv) except AttributeError: # sys.argv gives argv.error app = QtGui.QApplication([]) else: app = app_in self_quit = True else: app = QtGui.QApplication.instance() mainDialog = DialogClass(**kwargs) mainDialog.show() if executor is None: app.exec_() if self_quit: app.connect(app, QtCore.SIGNAL("lastWindowClosed()"), app, QtCore.SLOT("quit()")) else: executor.exec_(app, mainDialog) return mainDialog
def setup_ui(self): """create the UI widgets """ self.vertical_layout = QtWidgets.QVBoxLayout(self) self.setLayout(self.vertical_layout) # the widget should consist of a QGraphic self.thumbnail_graphics_view = QtWidgets.QGraphicsView(self) # set size policy size_policy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(0) size_policy.setHeightForWidth( self.thumbnail_graphics_view.sizePolicy().hasHeightForWidth()) self.thumbnail_graphics_view.setSizePolicy(size_policy) # set size default_size = QtCore.QSize(*self.default_thumbnail_size) self.thumbnail_graphics_view.setMinimumSize(default_size) self.thumbnail_graphics_view.setMaximumSize(default_size) self.thumbnail_graphics_view.setAutoFillBackground(False) self.thumbnail_graphics_view.setVerticalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff) self.thumbnail_graphics_view.setHorizontalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff) brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) brush.setStyle(QtCore.Qt.SolidPattern) self.thumbnail_graphics_view.setBackgroundBrush(brush) self.thumbnail_graphics_view.setInteractive(False) self.thumbnail_graphics_view.setRenderHints( QtGui.QPainter.Antialiasing | QtGui.QPainter.HighQualityAntialiasing | QtGui.QPainter.SmoothPixmapTransform | QtGui.QPainter.TextAntialiasing) self.vertical_layout.addWidget(self.thumbnail_graphics_view) self.upload_thumbnail_button = QtWidgets.QPushButton(self) self.upload_thumbnail_button.setText("Upload...") self.upload_thumbnail_button.setGeometry( self.thumbnail_graphics_view.geometry()) self.upload_thumbnail_button.setVisible(True) self.vertical_layout.addWidget(self.upload_thumbnail_button) # create signals # QtCore.QObject.connect( # self.thumbnail_graphics_view, # QtCore.SIGNAL("clicked()"), # self.thumbnail_graphics_view_clicked # ) QtCore.QObject.connect(self.upload_thumbnail_button, QtCore.SIGNAL("clicked()"), self.upload_thumbnail_button_clicked)
def __init__(self, *args, **kwargs): self.entity_type = kwargs.pop('entity_type', None) pixmap = QtGui.QPixmap(20, 20) super(TaskIcon, self).__init__(pixmap) loaded_font_families = load_font('FontAwesome.otf') # default_font = QtGui.QFont() self.icon_font = QtGui.QFont() if loaded_font_families: self.icon_font.setFamily(loaded_font_families[0]) self.icon_font.setPixelSize(14)
def paintEvent(self, event): """Overridden paint event :param event: QPaintEvent instance :return: """ super(ValidatedLineEdit, self).paintEvent(event) if self.icon is not None: painter = QtGui.QPainter(self) pixmap = self.icon.pixmap(self.height() - 6, self.height() - 6) x = self.width() - self.height() + 4 painter.drawPixmap(x, 3, pixmap) painter.setPen(QtGui.QColor("lightgrey")) painter.drawLine(x - 2, 3, x - 2, self.height() - 4)
def _setup_ui(self): self.setWindowModality(QtCore.Qt.ApplicationModal) self.setModal(True) self.resize(300, 300) size_policy = QtWidgets.QSizePolicy( QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred ) size_policy.setHorizontalStretch(1) size_policy.setVerticalStretch(1) size_policy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(size_policy) self.setSizeGripEnabled(True) self.horizontal_layout = QtWidgets.QHBoxLayout(self) self.toolbox_widget = QtWidgets.QWidget(self) self.horizontal_layout.addWidget(self.toolbox_widget) self.toolbox_layout = ToolboxLayout(self.toolbox_widget) self.toolbox_layout.setSizeConstraint(QtWidgets.QLayout.SetMaximumSize) self.toolbox_layout.setContentsMargins(0, 0, 0, 0) # setup icon global __here__ icon_path = os.path.abspath( os.path.join(__here__, "../../../ui/images/fusion9.png") ) icon = QtGui.QIcon(icon_path) self.setWindowIcon(icon)
def get_icon(icon_name): """Returns an icon from ui library """ here = os.path.abspath(os.path.dirname(__file__)) images_path = os.path.join(here, 'images') icon_full_path = os.path.join(images_path, icon_name) return QtGui.QIcon(icon_full_path)
def update_gview_with_image_file(image_full_path, gview): """updates the QGraphicsView with the given image """ if not isinstance(gview, QtWidgets.QGraphicsView): return clear_thumbnail(gview) if image_full_path != "": image_full_path = os.path.normpath(image_full_path) image_format = os.path.splitext(image_full_path)[-1].replace( '.', '').upper() logger.debug("creating pixmap from: %s" % image_full_path) # size = conf.thumbnail_size # width = size[0] # height = size[1] size = gview.size() width = size.width() height = size.height() logger.debug('width: %s' % width) logger.debug('height: %s' % height) if os.path.exists(image_full_path): pixmap = QtGui.QPixmap(image_full_path, format=image_format).scaled( width, height, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation) # pixmap = QtGui.QPixmap(image_full_path, format='JPG') scene = gview.scene() scene.addPixmap(pixmap)
def setup_ui(self): """create the UI widgets """ self.vertical_layout = QtWidgets.QVBoxLayout(self) from anima.ui.lib import QtCore, QtGui # the widget should consist of a QGraphic self.thumbnail_graphics_view = QtWidgets.QGraphicsView(self) # set size policy size_policy = QtWidgets.QSizePolicy( QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed ) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(0) size_policy.setHeightForWidth( self.thumbnail_graphics_view.sizePolicy().hasHeightForWidth()) self.thumbnail_graphics_view.setSizePolicy(size_policy) # set size default_size = QtCore.QSize( self.default_thumbnail_size, self.default_thumbnail_size ) self.thumbnail_graphics_view.setMinimumSize(default_size) self.thumbnail_graphics_view.setMaximumSize(default_size) self.thumbnail_graphics_view.setAutoFillBackground(False) self.thumbnail_graphics_view.setVerticalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff ) self.thumbnail_graphics_view.setHorizontalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff ) brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) brush.setStyle(QtCore.Qt.SolidPattern) self.thumbnail_graphics_view.setBackgroundBrush(brush) self.thumbnail_graphics_view.setInteractive(False) self.thumbnail_graphics_view.setRenderHints( QtGui.QPainter.Antialiasing | QtGui.QPainter.HighQualityAntialiasing | QtGui.QPainter.SmoothPixmapTransform | QtGui.QPainter.TextAntialiasing ) self.vertical_layout.addWidget(self.thumbnail_graphics_view)
def _show_versions_treeView_context_menu(self, position): """the custom context menu for the versions_treeView """ # convert the position to global screen position global_position = \ self.versions_treeView.mapToGlobal(position) index = self.versions_treeView.indexAt(position) model = self.versions_treeView.model() # get the column 0 item which holds the Version instance # index = self.versions_treeView.model().index(index.row(), 0) item = model.itemFromIndex(index) logger.debug('itemAt(position) : %s' % item) if not item: return if not hasattr(item, 'version'): return version = item.version latest_published_version = None if version: latest_published_version = version.latest_published_version item_action = item.action # if item_action != 'create': # return from stalker import Version if not isinstance(version, Version): return # create the menu menu = QtGui.QMenu() # Add "Open..." action # Always open the latest published version absolute_full_path = version.absolute_full_path if absolute_full_path: action = menu.addAction('Open...') if latest_published_version: action.version = latest_published_version else: action.version = version selected_action = menu.exec_(global_position) if selected_action: choice = selected_action.text() if choice == 'Open...': self.open_version(selected_action.version)
def set_published_font(item): """sets the font for the given item :param item: the a QTableWidgetItem """ my_font = item.font() my_font.setBold(True) item.setFont(my_font) foreground = item.foreground() foreground.setColor(QtGui.QColor(0, 192, 0)) item.setForeground(foreground)
def update(self, completion_prefix): tasks = Task.query \ .filter(Task.name.ilike('%' + completion_prefix + '%')) \ .all() logger.debug('completer tasks : %s' % tasks) task_names = [task.name for task in tasks] model = QtGui.QStringListModel(task_names) self.setModel(model) # self.setCompletionPrefix(completion_prefix) self.setCompletionPrefix('') # if completion_prefix.strip() != '': self.complete()
def send_edl(self, edl_path, media_path): """Sends the edl with the given path to AVID, also copies the MXF files to the media folder path :param edl_path: The edl path :param media_path: The AVID media files path """ # get the source clips from edl import edl parser = edl.Parser('24') # just use some random frame rate with open(edl_path) as f: l = parser.parse(f) total_item_count = len(l) + 1 progress_dialog = QtGui.QProgressDialog(self) progress_dialog.setRange(0, total_item_count) progress_dialog.setLabelText('Copying MXF files...') progress_dialog.show() step = 0 progress_dialog.setValue(step) for event in l: # assert isinstance(event, edl.Event) mov_full_path = event.source_file mxf_full_path = os.path.expandvars( os.path.splitext(mov_full_path)[0] + '.mxf' ) target_mxf_path = os.path.expandvars( os.path.join( media_path, os.path.basename(mxf_full_path) ) ) shutil.copy( mxf_full_path, target_mxf_path ) step += 1 progress_dialog.setValue(step) # and call EDL_Manager.exe with the edl_path progress_dialog.setLabelText('Calling EDL Manager...') step += 1 progress_dialog.setValue(step) subprocess.call(['EDL_Mgr', os.path.normcase(edl_path)], shell=False)
def clear_thumbnail(gview): """Clears the thumbnail for the given QGraphicsView :param gview: The QGraphicsView instance """ if not gview: return # clear the graphics scene in case there is no thumbnail scene = gview.scene() if not scene: scene = QtGui.QGraphicsScene(gview) gview.setScene(scene) scene.clear()
def update_versions(self): """updates the versions if it is checked in the UI """ reference_resolution = self.generate_reference_resolution() # send them back to environment try: self.environment.update_versions(reference_resolution) except RuntimeError as e: # display as a Error message and return without doing anything message_box = QtGui.QMessageBox(self) message_box.critical(self, "Error", str(e), QtGui.QMessageBox.Ok) return # close the interface self.close()
def create_dialog(self): """creates the progressWindow """ if self.use_ui: if self.dialog is None: from anima.ui.lib import QtCore, QtGui self.dialog = \ QtGui.QProgressDialog(None, QtCore.Qt.WindowStaysOnTopHint) # self.dialog.setMinimumDuration(2000) self.dialog.setRange(0, self.max_steps) self.dialog.setLabelText(self.title) # self.dialog.setAutoClose(True) # self.dialog.setAutoReset(True) self.center_window() self.dialog.show() # also set the Manager to in progress self.in_progress = True
def setup_ui(self): """create the main """ tlb = ToolboxLayout() self.setLayout(tlb) # setup icon global __here__ icon_path = os.path.abspath( os.path.join(__here__, "../../../ui/images/DaVinciResolve.png")) try: icon = QtWidgets.QIcon(icon_path) except AttributeError: icon = QtGui.QIcon(icon_path) self.setWindowIcon(icon) self.setWindowTitle("DaVinci Resolve Toolbox")
def setup_ui(self): """creates the UI widgets """ self.setWindowTitle("%s v%s" % (self.__app_name__, self.__version__)) # set application icon from anima import ui import os print('ui.__path__: %s' % ui.__path__[0]) app_icon_path = os.path.join(ui.__path__[0], 'images', 'app_icon.png') self.setWindowIcon(QtGui.QIcon(app_icon_path)) self.create_main_menu() self.create_toolbars() self.create_dock_widgets() self.read_settings()
def get_icon(icon_name): """Returns an icon from ui library """ import time start_time = time.time() # get the icon from cache if possible from anima.ui import ICON_CACHE q_icon = ICON_CACHE.get(icon_name) if not q_icon: logger.debug("getting icon from the cache!") # use the local icon cache import os from anima import defaults local_icon_cache_path = os.path.normpath( os.path.expanduser( os.path.join(defaults.local_cache_folder, "icons"))) local_icon_full_path = os.path.join(local_icon_cache_path, "%s.png" % icon_name) logger.debug("local_icon_full_path: %s" % local_icon_full_path) if not os.path.exists(local_icon_full_path): logger.debug("local icon cache not found: %s" % icon_name) logger.debug("retrieving icon from library!") here = os.path.abspath(os.path.dirname(__file__)) images_path = os.path.join(here, 'images') icon_full_path = os.path.join(images_path, "%s.png" % icon_name) logger.debug("icon_full_path: %s" % icon_full_path) # copy to local cache folder try: os.makedirs(local_icon_cache_path) except OSError: pass import shutil try: shutil.copy(icon_full_path, local_icon_full_path) except OSError: # original icon doesn't exist pass q_icon = QtGui.QIcon(local_icon_full_path) ICON_CACHE[icon_name] = q_icon logger.debug("get_icon took: %0.6f s" % (time.time() - start_time)) return q_icon
def generate_version_row(cls, parent, pseudo_model, version): """Generates a new version row :return: """ # column 0 version_item = VersionItem(0, 0) version_item.parent = parent version_item.pseudo_model = pseudo_model version_item.version = version version_item.setEditable(False) reference_resolution = pseudo_model.reference_resolution if version in reference_resolution['update']: action = 'update' font_color = QtGui.QColor(192, 128, 0) if version in reference_resolution['root']: version_item.setCheckable(True) version_item.setCheckState(QtCore.Qt.Checked) elif version in reference_resolution['create']: action = 'create' font_color = QtGui.QColor(192, 0, 0) if version in reference_resolution['root']: version_item.setCheckable(True) version_item.setCheckState(QtCore.Qt.Checked) else: font_color = QtGui.QColor(0, 192, 0) action = '' version_item.action = action set_item_color(version_item, font_color) # thumbnail thumbnail_item = QtGui.QStandardItem() thumbnail_item.setEditable(False) # thumbnail_item.setText('no thumbnail') thumbnail_item.version = version thumbnail_item.action = action set_item_color(thumbnail_item, font_color) # Nice Name nice_name_item = QtGui.QStandardItem() nice_name_item.toolTip() nice_name_item.setText('%s_v%s' % (version.nice_name, ('%s' % version.version_number).zfill(3))) nice_name_item.setEditable(False) nice_name_item.version = version nice_name_item.action = action set_item_color(nice_name_item, font_color) # Take take_item = QtGui.QStandardItem() take_item.setEditable(False) take_item.setText(version.take_name) take_item.version = version take_item.action = action set_item_color(take_item, font_color) # Current current_version_item = QtGui.QStandardItem() current_version_item.setText('%s' % version.version_number) current_version_item.setEditable(False) current_version_item.version = version current_version_item.action = action set_item_color(current_version_item, font_color) # Latest latest_published_version = version.latest_published_version latest_published_version_item = QtGui.QStandardItem() latest_published_version_item.version = version latest_published_version_item.action = action latest_published_version_item.setEditable(False) latest_published_version_text = 'No Published Version' if latest_published_version: latest_published_version_text = '%s' % \ latest_published_version.version_number latest_published_version_item.setText(latest_published_version_text) set_item_color(latest_published_version_item, font_color) # Action action_item = QtGui.QStandardItem() action_item.setEditable(False) action_item.setText(action) action_item.version = version action_item.action = action set_item_color(action_item, font_color) # Updated By updated_by_item = QtGui.QStandardItem() updated_by_item.setEditable(False) updated_by_text = '' if latest_published_version and latest_published_version.updated_by: updated_by_text = latest_published_version.updated_by.name updated_by_item.setText(updated_by_text) updated_by_item.version = version updated_by_item.action = action set_item_color(updated_by_item, font_color) # Description description_item = QtGui.QStandardItem() if latest_published_version: description_item.setText(latest_published_version.description) description_item.setEditable(False) description_item.version = version description_item.action = action set_item_color(description_item, font_color) # # Path # path_item = QtGui.QStandardItem() # if latest_published_version: # path_item.setText(version.absolute_full_path) # path_item.setEditable(True) # set_item_color(path_item, font_color) return [ version_item, thumbnail_item, nice_name_item, take_item, current_version_item, latest_published_version_item, action_item, updated_by_item, description_item ]
def fetchMore(self): logger.debug('TaskItem.fetchMore() is started for item: %s' % self.text()) if self.canFetchMore(): from sqlalchemy.orm import aliased from sqlalchemy.dialects.postgresql import array_agg from stalker import Task, User from stalker.models.task import Task_Resources from stalker.db.session import DBSession inner_tasks = aliased(Task) subquery = DBSession.query(Task.id) \ .filter(Task.id == inner_tasks.parent_id) query = DBSession.query( Task.id, Task.name, Task.entity_type, Task.status_id, subquery.exists().label('has_children'), array_agg(User.name).label('resources') ) \ .outerjoin(Task_Resources, Task.__table__.c.id == Task_Resources.c.task_id) \ .outerjoin(User, Task_Resources.c.resource_id == User.id) \ .group_by( Task.id, Task.name, Task.entity_type, Task.status_id, subquery.exists().label('has_children') ) if self.task.entity_type != 'Project': # query child tasks query = query.filter(Task.parent_id == self.task.id) else: # query only root tasks query = query.filter(Task.project_id == self.task.id)\ .filter(Task.parent_id==None) tasks = query.order_by(Task.name).all() # # model = self.model() # This will cause a SEGFAULT # # TODO: update it later on # start = time.time() from anima import defaults task_items = [] for task in tasks: task_item = TaskItem(0, 4, task=task) task_item.parent = self # color with task status task_item.setData( QtGui.QColor( *defaults.status_colors_by_id[task.status_id]), QtCore.Qt.BackgroundRole) # use black text task_item.setForeground(QtGui.QBrush(QtGui.QColor(0, 0, 0))) task_items.append(task_item) if task_items: # self.appendRows(task_items) for task_item in task_items: # TODO: Create a custom QStandardItem for each data type in different columns entity_type_item = QtGui.QStandardItem() entity_type_item.setData(task_item.task.entity_type, QtCore.Qt.DisplayRole) resources_item = QtGui.QStandardItem() if task_item.task.resources != [None]: resources_item.setData( ', '.join(map(str, task_item.task.resources)), QtCore.Qt.DisplayRole) self.appendRow( [task_item, entity_type_item, resources_item]) self.fetched_all = True logger.debug('TaskItem.fetchMore() is finished for item: %s' % self.text())
def fetchMore(self): logger.debug( 'TaskItem.fetchMore() is started for item: %s' % self.text() ) if self.canFetchMore(): tasks = [] if self.task_name is None: self.task_name, self.task_entity_type = \ db.DBSession \ .query(SimpleEntity.name, SimpleEntity.entity_type) \ .filter(SimpleEntity.id == self.task_id) \ .first() if self.task_children_data is None: if self.task_entity_type in self.task_entity_types: self.task_children_data = db.DBSession \ .query(Task.id, Task.name, Task.entity_type, Task.status_id) \ .filter(Task.parent_id == self.task_id) \ .order_by(Task.name) \ .all() elif self.task_entity_type == 'Project': self.task_children_data = db.DBSession\ .query(Task.id, Task.name, Task.entity_type, Task.status_id) \ .filter(Task.parent_id == None) \ .filter(Task.project_id == self.task_id) \ .order_by(Task.name) \ .all() tasks = self.task_children_data # # model = self.model() # This will cause a SEGFAULT # # TODO: update it later on # if self.user_tasks_only: # user_tasks_and_parents = [] # # need to filter tasks which do not belong to user # for task in tasks: # for user_task in self.user.tasks: # if task in user_task.parents or \ # task is user_task or \ # task in self.user.projects: # user_tasks_and_parents.append(task) # break # # tasks = user_tasks_and_parents # # tasks = sorted(tasks, key=lambda x: x.name) # start = time.time() task_items = [] for task in tasks: task_item = TaskItem(0, 3) task_item.parent = self task_item.task_id = task[0] task_item.user_id = self.user_id task_item.user_tasks_only = self.user_tasks_only # set the font # name_item = QtGui.QStandardItem(task.name) # entity_type_item = QtGui.QStandardItem(task.entity_type) # task_item.setItem(0, 0, name_item) # task_item.setItem(0, 1, entity_type_item) task_item.setText(task[1]) # make_bold = False # if task_item.canFetchMore(): # make_bold = True # if task[2] in self.task_entity_types: # children_count = \ # db.DBSession.query(Task.id)\ # .filter(Task.parent_id == task[0])\ # .count() # if children_count: # make_bold = True # elif task[2] == 'Project': # make_bold = True # if make_bold: # my_font = task_item.font() # my_font.setBold(True) # task_item.setFont(my_font) # color with task status task_item.setData( QtGui.QColor( *status_colors_by_id[task[3]] ), QtCore.Qt.BackgroundRole ) # use black text task_item.setForeground( QtGui.QBrush(QtGui.QColor(0, 0, 0)) ) task_items.append(task_item) if task_items: self.appendRows(task_items) self.fetched_all = True logger.debug( 'TaskItem.fetchMore() is finished for item: %s' % self.text() )
def fetchMore(self): logger.debug( 'TaskItem.fetchMore() is started for item: %s' % self.text() ) if self.canFetchMore(): from sqlalchemy import alias from stalker import Task from stalker.db.session import DBSession inner_tasks = alias(Task.__table__) subquery = DBSession.query(Task.id)\ .filter(Task.id == inner_tasks.c.parent_id) query = DBSession.query( Task.id, Task.name, Task.entity_type, Task.status_id, subquery.exists().label('has_children') ) if self.task.entity_type != 'Project': # query child tasks query = query.filter(Task.parent_id == self.task.id) else: # query only root tasks query = query.filter(Task.project_id == self.task.id)\ .filter(Task.parent_id==None) tasks = query.order_by(Task.name).all() # # model = self.model() # This will cause a SEGFAULT # # TODO: update it later on # start = time.time() from anima import defaults task_items = [] for task in tasks: task_item = TaskItem(0, 3, entity=task) task_item.parent = self # color with task status task_item.setData( QtGui.QColor( *defaults.status_colors_by_id[task.status_id] ), QtCore.Qt.BackgroundRole ) # use black text task_item.setForeground( QtGui.QBrush(QtGui.QColor(0, 0, 0)) ) task_items.append(task_item) if task_items: self.appendRows(task_items) self.fetched_all = True logger.debug( 'TaskItem.fetchMore() is finished for item: %s' % self.text() )
def fill_calendar_with_time_logs(self): """fill the calendar with daily time log info """ resource_id = self.get_current_resource_id() # do not update if the calendar is showing the same user if self.calendar_widget.resource_id == resource_id or resource_id == -1: return tool_tip_text_format = u'{start:%H:%M} - {end:%H:%M} | {task_name}' # import time # start = time.time() # get all the TimeLogs grouped daily sql = """-- TOP DOWN SEARCH -- select "TimeLogs".start::date as date, array_agg(task_rec_data.full_path) as task_name, array_agg("TimeLogs".start) as start, array_agg("TimeLogs".end) as end, sum(extract(epoch from ("TimeLogs".end - "TimeLogs".start))) from "TimeLogs" join ( with recursive recursive_task(id, parent_id, path_names) as ( select task.id, task.project_id, -- task.project_id::text as path, ("Projects".code || '') as path_names from "Tasks" as task join "Projects" on task.project_id = "Projects".id where task.parent_id is NULL union all select task.id, task.parent_id, -- (parent.path || '|' || task.parent_id:: text) as path, (parent.path_names || ' | ' || "Parent_SimpleEntities".name) as path_names from "Tasks" as task inner join recursive_task as parent on task.parent_id = parent.id inner join "SimpleEntities" as "Parent_SimpleEntities" on parent.id = "Parent_SimpleEntities".id ) select recursive_task.id, "SimpleEntities".name || ' (' || recursive_task.path_names || ')' as full_path from recursive_task join "SimpleEntities" on recursive_task.id = "SimpleEntities".id ) as task_rec_data on "TimeLogs".task_id = task_rec_data.id -- getting all the data is as fast as getting one, so get all the TimeLogs of this user where "TimeLogs".resource_id = :resource_id group by cast("TimeLogs".start as date) order by cast("TimeLogs".start as date) """ from sqlalchemy import text from stalker.db.session import DBSession result = DBSession.connection().execute( text(sql), resource_id=resource_id ).fetchall() # end = time.time() # print('getting data from sql: %0.3f sec' % (end - start)) from anima.utils import utc_to_local time_shifter = utc_to_local import stalker # TODO: Remove this in a later version from distutils.version import LooseVersion if LooseVersion(stalker.__version__) >= LooseVersion('0.2.18'): def time_shifter(x): return x for r in result: calendar_day = r[0] year = calendar_day.year month = calendar_day.month day = calendar_day.day daily_logged_seconds = r[4] daily_logged_hours = daily_logged_seconds // 3600 daily_logged_minutes = \ (daily_logged_seconds - daily_logged_hours * 3600) // 60 tool_tip_text_data = [ u'Total: %i h %i min logged' % (daily_logged_hours, daily_logged_minutes) if daily_logged_hours else u'Total: %i min logged' % daily_logged_minutes ] for task_name, start, end in sorted( zip(r[1], r[2], r[3]), key=lambda x: x[1]): time_log_tool_tip_text = tool_tip_text_format.format( start=time_shifter(start), end=time_shifter(end), task_name=task_name ) tool_tip_text_data.append(time_log_tool_tip_text) merged_tool_tip = u'\n'.join(tool_tip_text_data) date_format = QtGui.QTextCharFormat() bg_brush = QtGui.QBrush() bg_brush.setColor( QtGui.QColor(0, 255.0 / 86400.0 * daily_logged_seconds, 0) ) date_format.setBackground(bg_brush) date_format.setToolTip(merged_tool_tip) date = QtCore.QDate(year, month, day) self.calendar_widget.setDateTextFormat(date, date_format)
def fetchMore(self): logger.debug( 'TaskItem.fetchMore() is started for item: %s' % self.text() ) if self.canFetchMore(): tasks = [] if isinstance(self.task, Task): tasks = self.task.children elif isinstance(self.task, Project): tasks = self.task.root_tasks # model = self.model() # This will cause a SEGFAULT if self.user_tasks_only: user_tasks_and_parents = [] # need to filter tasks which do not belong to user for task in tasks: for user_task in self.user.tasks: if task in user_task.parents or \ task is user_task or \ task in self.user.projects: user_tasks_and_parents.append(task) break tasks = user_tasks_and_parents tasks = sorted(tasks, key=lambda x: x.name) for task in tasks: task_item = TaskItem(0, 3) task_item.parent = self task_item.task = task task_item.user = self.user task_item.user_tasks_only = self.user_tasks_only # set the font # name_item = QtGui.QStandardItem(task.name) # entity_type_item = QtGui.QStandardItem(task.entity_type) # task_item.setItem(0, 0, name_item) # task_item.setItem(0, 1, entity_type_item) task_item.setText(task.name) make_bold = False if isinstance(task, Task): if task.is_container: make_bold = True elif isinstance(task, Project): make_bold = True if make_bold: my_font = task_item.font() my_font.setBold(True) task_item.setFont(my_font) # color with task status task_item.setData( QtGui.QColor( *status_colors[task_item.task.status.code.lower()] ), QtCore.Qt.BackgroundRole ) # use black text task_item.setForeground( QtGui.QBrush(QtGui.QColor(0, 0, 0)) ) self.appendRow(task_item) self.fetched_all = True logger.debug( 'TaskItem.fetchMore() is finished for item: %s' % self.text() )
def setup_ui(self, dialog): """Sets up the dialog :param dialog: QtGui.QDialog instance :return: """ dialog.setObjectName("Dialog") dialog.setWindowModality(QtCore.Qt.ApplicationModal) dialog.resize(1200, 800) # layout vertical first self.vertical_layout = QtGui.QVBoxLayout(dialog) self.vertical_layout.setObjectName('verticalLayout1') self.horizontal_layout = QtGui.QHBoxLayout() self.from_task_tree_view = QtGui.QTreeView(dialog) self.from_task_tree_view.setObjectName("from_tasks_treeView") self.copy_push_button = QtGui.QPushButton(dialog) self.copy_push_button.setObjectName("copy_push_button") self.copy_push_button.setText('>') self.to_task_tree_view = TaskTreeView(dialog) self.to_task_tree_view.setObjectName("to_tasks_treeView") # self.horizontal_layout1.addWidget(self.from_task_tree_view) self.horizontal_layout.addWidget(self.from_task_tree_view) self.horizontal_layout.addWidget(self.copy_push_button) self.horizontal_layout.addWidget(self.to_task_tree_view) self.vertical_layout.addLayout(self.horizontal_layout) self.horizontal_layout_2 = QtGui.QHBoxLayout() self.horizontal_layout_2.setContentsMargins(-1, 10, -1, -1) self.horizontal_layout_2.setObjectName("horizontal_layout_2") self.vertical_layout.addLayout(self.horizontal_layout_2) QtCore.QMetaObject.connectSlotsByName(dialog) # initialize elements logged_in_user = self.get_logged_in_user() projects = Project.query.order_by(Project.name).all() task_tree_model = TaskTreeModel() task_tree_model.user = logged_in_user task_tree_model.populateTree(projects) # fit to elements self.from_tasks_tree_view_auto_fit_column() self.to_tasks_tree_view_auto_fit_column() self.from_task_tree_view.setModel(task_tree_model) self.to_task_tree_view.setModel(task_tree_model) # setup signals # tasks_treeView QtCore.QObject.connect( self.from_task_tree_view.selectionModel(), QtCore.SIGNAL('selectionChanged(const QItemSelection &, ' 'const QItemSelection &)'), self.from_task_tree_view_changed ) QtCore.QObject.connect( self.to_task_tree_view.selectionModel(), QtCore.SIGNAL('selectionChanged(const QItemSelection &, ' 'const QItemSelection &)'), self.to_task_tree_view_changed ) # fit column 0 on expand/collapse QtCore.QObject.connect( self.from_task_tree_view, QtCore.SIGNAL('expanded(QModelIndex)'), self.from_tasks_tree_view_auto_fit_column ) QtCore.QObject.connect( self.to_task_tree_view, QtCore.SIGNAL('expanded(QModelIndex)'), self.to_tasks_tree_view_auto_fit_column ) # copy_push_button QtCore.QObject.connect( self.copy_push_button, QtCore.SIGNAL("clicked()"), self.copy_versions )
def update_content(self, versions): """updates the content with the given versions data """ import os import datetime logger.debug('VersionsTableWidget.update_content() is started') self.clear() self.versions = versions self.setRowCount(len(versions)) def set_published_font(item): """sets the font for the given item :param item: the a QTableWidgetItem """ my_font = item.font() my_font.setBold(True) item.setFont(my_font) foreground = item.foreground() foreground.setColor(QtGui.QColor(0, 192, 0)) item.setForeground(foreground) # update the previous versions list from anima import defaults for i, version in enumerate(versions): is_published = version.is_published absolute_full_path = os.path.normpath( os.path.expandvars(version.full_path)).replace('\\', '/') version_file_exists = os.path.exists(absolute_full_path) c = 0 # ------------------------------------ # version_number item = QtWidgets.QTableWidgetItem(str(version.version_number)) # align to center and vertical center item.setTextAlignment(0x0004 | 0x0080) if is_published: set_published_font(item) if not version_file_exists: item.setBackground(QtGui.QColor(64, 0, 0)) self.setItem(i, c, item) c += 1 # ------------------------------------ # ------------------------------------ # created_with item = QtWidgets.QTableWidgetItem() if version.created_with: from anima.ui import utils as ui_utils item.setIcon(ui_utils.get_icon(version.created_with.lower())) if is_published: set_published_font(item) if not version_file_exists: item.setBackground(QtGui.QColor(64, 0, 0)) self.setItem(i, c, item) c += 1 # ------------------------------------ # ------------------------------------ # user.name created_by = '' if version.created_by_id: created_by = defaults.user_names_lut[version.created_by_id] item = QtWidgets.QTableWidgetItem(created_by) # align to left and vertical center item.setTextAlignment(0x0001 | 0x0080) if is_published: set_published_font(item) if not version_file_exists: item.setBackground(QtGui.QColor(64, 0, 0)) self.setItem(i, c, item) c += 1 # ------------------------------------ # ------------------------------------ # user.name updated_by = '' if version.updated_by_id: updated_by = defaults.user_names_lut[version.updated_by_id] item = QtWidgets.QTableWidgetItem(updated_by) # align to left and vertical center item.setTextAlignment(0x0001 | 0x0080) if is_published: set_published_font(item) if not version_file_exists: item.setBackground(QtGui.QColor(64, 0, 0)) self.setItem(i, c, item) c += 1 # ------------------------------------ # ------------------------------------ # file size # get the file size # file_size_format = "%.2f MB" file_size = -1 if version_file_exists: file_size = float( os.path.getsize(absolute_full_path)) / 1048576 from anima import defaults item = QtWidgets.QTableWidgetItem(defaults.file_size_format % file_size) # align to left and vertical center item.setTextAlignment(0x0001 | 0x0080) if is_published: set_published_font(item) if not version_file_exists: item.setBackground(QtGui.QColor(64, 0, 0)) self.setItem(i, c, item) c += 1 # ------------------------------------ # ------------------------------------ # date # get the file date file_date = datetime.datetime.today() if version_file_exists: file_date = datetime.datetime.fromtimestamp( os.path.getmtime(absolute_full_path)) item = QtWidgets.QTableWidgetItem( file_date.strftime(defaults.date_time_format)) # align to left and vertical center item.setTextAlignment(0x0001 | 0x0080) if is_published: set_published_font(item) if not version_file_exists: item.setBackground(QtGui.QColor(64, 0, 0)) self.setItem(i, c, item) c += 1 # ------------------------------------ # ------------------------------------ # description item = QtWidgets.QTableWidgetItem(version.description) # align to left and vertical center item.setTextAlignment(0x0001 | 0x0080) if is_published: set_published_font(item) if not version_file_exists: item.setBackground(QtGui.QColor(64, 0, 0)) self.setItem(i, c, item) c += 1 # ------------------------------------ # resize the first column self.resizeRowsToContents() self.resizeColumnsToContents() self.resizeRowsToContents() logger.debug('VersionsTableWidget.update_content() is finished')