import gtk
import gobject
from WorkshopListItem import WorkshopListItem
from Rating import Rating
from WorkshopModel import WorkshopModel
from WorkshopController import WorkshopController
from dialogs import InfoDialog
import operator
class WorkshopView(gtk.Alignment):
"""
Main container for the Workshop Mytutorial Part
"""
def __init__(self):
"""
Constructor
"""
gtk.Alignment.__init__(self,0.0,0.0,1.0,1.0)
#Register Rating as a gobject
gobject.type_register(Rating)
#create the model and the controller
self.model = WorkshopModel(self)
self.controller = WorkshopController(self,self.model)
#Create the main view
self.mainView = WorkshopMain(self.controller)
self.detailView = None
#display the main view
self.add(self.mainView)
self.mainView.show()
#display all tutorials
self.controller.tutorial_query(None,None)
def set_tutorial_list(self,tutorial_list):
"""
Set the list of tutorial to display in the main View
Refresh the View
@param tutorial_list the list of tutorial
"""
self.mainView.set_tutorial_list(tutorial_list)
def change_sorting(self,sorting_key):
"""
Sort the list of tutorial base on the sorting_key
@param sorting_key the tutorial metadata to use to sort the tutorials
"""
self.mainView.change_sorting(sorting_key)
def display_detail(self,tutorial):
"""
Displays the detail view of a tutorial
@param tutorial the tutorial to display
"""
#hide the main view
self.mainView.hide()
self.remove(self.mainView)
#create the detail view and show it
self.detailView = WorkshopDetail(tutorial,self.controller)
self.add(self.detailView)
self.detailView.show()
def display_main_view(self):
"""
Displays the main view of the Workshop
"""
#hide the detail view
self.detailView.hide()
self.remove(self.detailView)
#display the main view
self.add(self.mainView)
self.mainView.show()
def display_info_dialog(self,tutorial):
"""
Displays the infos dialog on a tutorial
@param tutorial the tutorial to edit
"""
infoDialog = InfoDialog(tutorial,self.controller)
infoDialog.run()
infoDialog.destroy()
@staticmethod
def display_login():
loginDialog = LoginDialog()
loginDialog.run()
loginDialog.destroy()
def refresh_content(self):
"""
Refresh the data displayed
"""
#refresh the tutorial list
self.mainView.refresh_tutorial_display()
#refresh the detail view
self.detailView.refresh_content()
class WorkshopMain(gtk.VBox):
"""
Contains the main view for the Workshop My tutorial
"""
def __init__(self,controller):
"""Constructor
@param controller The controller to attach the view to
"""
gtk.VBox.__init__(self,False,10)
self.controller = controller
self.tutorial_list = []
#by default tutorials are sorted by name
self.sorting_key = 'Name'
self.set_border_width(10)
#The searchbar is displayed at the top
self.search_bar = SearchBar(self.controller)
self.pack_start(self.search_bar,False,False)
#Add a separator after the search bar
sep = gtk.HSeparator()
self.pack_start(sep,False,False)
#create the list item container with a scroll bar if necessary
self.main_container = gtk.ScrolledWindow()
self.main_container.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
self.list_container= gtk.VBox()
self.main_container.add_with_viewport(self.list_container)
self.pack_start(self.main_container)
#Show the components
self.search_bar.show()
self.list_container.show()
self.main_container.show()
sep.show()
def change_sorting(self,sorting):
"""
Changes the property by which tutorial are sorted
@param sorting The property by which tutorials will be sorted
"""
self.sorting_key = sorting
self.sort_tutorial()
def sort_tutorial(self):
"""
Sorts the tutorials
"""
#if tutorials are sorted by rating they are in the reverse order
self.tutorial_list.sort(key=operator.attrgetter(self.sorting_key.lower()))
self.refresh_tutorial_display()
def set_tutorial_list(self,tutorial_list):
"""
Set the list of tutorial to display
@param tutorial_list the tutorial list
"""
self.tutorial_list = tutorial_list
self.sort_tutorial()
def refresh_tutorial_display(self):
"""
Refresh the tutorial content by deleting every item and recreating them
"""
#delete every tutorial list item
for child in self.list_container.get_children():
self.list_container.remove(child)
#Creates and add a new item for every tutorial
for tuto in self.tutorial_list:
item = WorkshopListItem(tuto,self.controller)
self.list_container.pack_start(item)
item.show()
class SearchBar(gtk.HBox):
"""
The search bar control for the Workshop My tutorial
"""
def __init__(self,controller):
"""
Constructor
@param controller The controller to link the view to
"""
gtk.HBox.__init__(self,False,10)
self.set_border_width(5)
self.controller = controller
#creating and configuring the controls
self.search_entry = gtk.Entry(400)
self.search_button = gtk.Button("Go")
self.separator = gtk.VSeparator()
self.sort_label = gtk.Label("Sort by")
self.sort_combo = gtk.combo_box_new_text()
self.sort_combo.insert_text(0,"Name")
self.sort_combo.insert_text(1,"Rating")
self.sort_combo.set_active(0)
self.selected_sorting = self.sort_combo.get_active_text()
#Adding the controls to the view
self.pack_start(self.search_entry,padding=5)
self.pack_start(self.search_button,False,False,padding=10)
self.pack_start(self.separator,False,False,padding=10)
self.pack_start(self.sort_label,False,False,padding=5)
self.pack_start(self.sort_combo,)
#showing the controls
self.search_entry.show()
self.search_button.show()
self.separator.show()
self.sort_label.show()
self.sort_combo.show()
#connecting the events
self.search_button.connect("clicked",self.controller.tutorial_query,self.search_entry.get_text())
self.sort_combo.connect("changed",self.controller.sort_selection_changed,None)
class WorkshopDetail(gtk.VBox):
def __init__(self,tutorial,controller):
"""
Constructor
@param tutorial The tutorial to display
@param controller The controller to link the view with
"""
#Used for string formatting
self.title_text = '%(title)s'
self.author_text = 'by %(author)s'
self.desc_text = 'Description: %(description)s'
self.controller = controller
self.tutorial = tutorial
gtk.VBox.__init__(self,False,10)
self.set_border_width(10)
#The first row contains the back button
first_row = gtk.HBox(False)
back_image = gtk.Image()
back_image.set_from_file('arrow_back.png')
self.back_button = gtk.Button("Back")
self.back_button.set_image(back_image)
first_row.pack_start(self.back_button,False,False)
#The second row contains the activity icon, the title label,
#the author label and the star rating
icon = gtk.Image()
icon.set_from_file('icon.svg')
label_holder = gtk.VBox(False,10)
self.title_label = gtk.Label("")
self.author_label = gtk.Label("")
#Add a small offsert for author's label alignement because it's cute
self.author_label.set_alignment(0.05,0.5)
self.title_label.set_alignment(0.0,0.5)
label_holder.pack_start(self.title_label)
label_holder.pack_start(self.author_label)
self.rating = Rating(tutorial,controller,rating = tutorial.rating)
second_row = gtk.HBox(False)
second_row.pack_start(icon,False,False)
second_row.pack_start(label_holder)
second_row.pack_end(self.rating,False,False)
#The middle of the screen contains an area for the description
self.desc_view = gtk.TextView()
self.desc_buff = gtk.TextBuffer()
self.desc_buff.set_text(tutorial.description)
self.desc_view.set_buffer(self.desc_buff)
self.desc_view.set_editable(False)
self.desc_view.set_wrap_mode(gtk.WRAP_WORD)
self.desc_view.set_cursor_visible(False)
self.desc_view.connect("realize",self.realize_cb,None)
self.desc_view.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse("gray") )
#The bottom of the screen contains the button(fourth and fifth row
self.launch_button = gtk.Button('Launch')
self.launch_button.get_child().set_markup(self.title_text %{"title":"Launch"})
self.edit_button = gtk.Button('Edit')
self.edit_button.get_child().set_markup(self.title_text %{"title":"Edit"})
self.update_button = gtk.Button('Update')
self.update_button.get_child().set_markup(self.title_text %{"title":"Update"})
self.info_button = gtk.Button('Infos')
self.info_button.get_child().set_markup(self.title_text %{"title":"Infos"})
self.delete_button = gtk.Button('Delete')
self.delete_button.get_child().set_markup(self.title_text %{"title":"Delete"})
fourth_row = gtk.HBox(False,15)
fourth_row.pack_start(self.launch_button,False,False)
fourth_row.pack_start(self.edit_button,False,False)
fourth_row.pack_start(self.update_button,False,False)
fourth_row.pack_start(self.info_button,False,False)
fourth_row.pack_end(self.delete_button,False,False)
self.publish_button = gtk.Button('')
self.publish_button.get_child().set_markup(self.title_text %{"title":"Publish"})
self.unpublish_button = gtk.Button('')
self.unpublish_button.get_child().set_markup(self.title_text %{"title":"Unpublish"})
fifth_row = gtk.HBox(False,15)
fifth_row.pack_start(self.publish_button,False,False)
fifth_row.pack_start(self.unpublish_button,False,False)
#The description view contains all the extra space
self.pack_start(first_row,False,False)
self.pack_start(second_row,False,False)
self.pack_start(self.desc_view)
self.pack_end(fifth_row,False,False)
self.pack_end(fourth_row,False,False)
#show everything
self.back_button.show()
first_row.show()
self.title_label.show()
self.author_label.show()
self.rating.show()
label_holder.show()
second_row.show()
icon.show()
self.desc_view.show()
self.launch_button.show()
self.edit_button.show()
self.update_button.show()
self.info_button.show()
self.delete_button.show()
fourth_row.show()
self.publish_button.show()
self.unpublish_button.show()
fifth_row.show()
#set some text with markup
self.title_label.set_markup(self.title_text % {"title":tutorial.name})
self.author_label.set_markup(self.author_text % {"author":tutorial.author})
#connect the clicked events of the buttons
self.back_button.connect("clicked",self.controller.back_pressed,None)
self.publish_button.connect("clicked",self.controller.publish_tutorial,self.tutorial)
self.unpublish_button.connect("clicked",self.controller.unpublish_tutorial,self.tutorial)
self.launch_button.connect("clicked",self.controller.launch_tutorial,self.tutorial)
self.edit_button.connect("clicked",self.controller.edit_tutorial,self.tutorial)
self.update_button.connect("clicked",self.controller.update_tutorial,self.tutorial)
self.info_button.connect("clicked",self.controller.info_tutorial,self.tutorial)
self.delete_button.connect("clicked",self.controller.delete_tutorial,self.tutorial)
def realize_cb(self,widget,data=None):
"""
This fucntion changes the cursor over the description view
So we see an arrow and not the insert text cursor
"""
widget.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR))
def refresh_content(self):
"""
Refresh the labels' text based on the tutorial object
"""
self.title_label.set_markup(self.title_text % {"title":self.tutorial.name})
self.author_label.set_markup(self.author_text % {"author":self.tutorial.author})
self.desc_buff.set_text(self.tutorial.description)
class WorkshopListItem(gtk.Alignment):
"""
A list item containing the details of a tutorial
"""
def __init__(self,tutorial,controller):
"""
Constructor
@param controller The controller to link the view to
"""
gtk.Alignment.__init__(self,0.0,0.0,1.0,1.0)
self.tutorial = tutorial
self.controller = controller
#The table will contain everything else
self.table = gtk.Table(3,3,False)
self.table.set_row_spacing(1,10)
#Create the controls
self.lbl_title = gtk.Label('')
self.lbl_title.set_alignment(0.0,0.5)
self.title_text = '%(title)s'
self.lbl_title.set_markup(self.title_text % {'title':tutorial.name})
self.lbl_desc = gtk.Label(tutorial.description)
self.lbl_desc.set_line_wrap(True)
self.lbl_desc.set_alignment(0.0,0.5)
self.btn_launch = gtk.Button('Launch')
launch_align= gtk.Alignment(0.0,1.0,0.0,0.0)
launch_align.add(self.btn_launch)
self.btn_details = gtk.Button('Details')
self.icon = gtk.Image()
self.icon.set_from_file('icon.svg')
self.rating = Rating(tutorial,controller,tutorial.rating, True)
#Add the controls to the table
self.table.attach(self.icon,0,1,0,1,0,0)
self.table.attach(self.lbl_title,1,2,0,1,yoptions=0)
self.table.attach(self.lbl_desc,1,2,1,2,xoptions=gtk.FILL,yoptions=gtk.EXPAND)
self.table.attach(launch_align,1,2,2,3,gtk.FILL)
self.table.attach(self.btn_details,2,3,2,3,0,0)
self.table.attach(self.rating,2,3,0,2,0,0)
#show everything
self.table.show()
self.icon.show()
self.lbl_title.show()
launch_align.show()
self.lbl_desc.show()
self.btn_launch.show()
self.btn_details.show()
self.rating.show()
self.add(self.table)
#connect the buttons
self.btn_details.connect("clicked",self.controller.show_details,self.tutorial)
self.btn_launch.connect("clicked",self.controller.launch_tutorial,self.tutorial)