From ff833a6ec7ef917422589df57169a87a05bf17b5 Mon Sep 17 00:00:00 2001 From: Charlie Date: Thu, 03 Dec 2009 12:10:02 +0000 Subject: The workshop --- (limited to 'Workshop.activity/Workshop.py') diff --git a/Workshop.activity/Workshop.py b/Workshop.activity/Workshop.py new file mode 100644 index 0000000..857bf8c --- /dev/null +++ b/Workshop.activity/Workshop.py @@ -0,0 +1,479 @@ +# Copyright (C) 2009, Tutorius.org +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +import gtk +import gobject + +from Rating import Rating +from WorkshopModel import WorkshopModel +from WorkshopController import WorkshopController +from dialogs import InfoDialog +import operator +import logging + +class WorkshopView(gtk.Alignment): + """ + Main container for the Workshop Mytutorial Part + """ + def __init__(self,model): + """ + 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.controller = WorkshopController(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() + + + + def set_categories(self,categories): + self.categories = categories + + 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 = MyTutorialDetail(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,self.categories) + infoDialog.run() + infoDialog.destroy() + + + def refresh_content(self): + """ + Refresh the data displayed + """ + #refresh the tutorial list + self.mainView.refresh_tutorial_display() + + #refresh the detail view + if self.detailView is not None: + 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 = MyTutorialListItem(tuto,self.controller) + self.list_container.pack_start(item) + item.show() + if self.tutorial_list[-1] != tuto: + sep = gtk.HSeparator() + self.list_container.pack_start(sep) + sep.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) + 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 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) + + #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() + + #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}) + + 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 + """ + #logging.info(tutorial.updated_metadata) + gtk.Alignment.__init__(self,0.0,0.0,1.0,1.0) + self.tutorial = tutorial + self.controller = controller + self.set_border_width(10) + + #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.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(self.rating,2,3,0,2,0,0) + + #show everything + self.table.show() + self.icon.show() + self.lbl_title.show() + self.lbl_desc.show() + self.rating.show() + + self.add(self.table) + + +class MyTutorialListItem(WorkshopListItem): + def __init__(self,tutorial,controller): + WorkshopListItem.__init__(self,tutorial,controller) + + self.last_row = gtk.HBox(False,15) + self.btn_launch = gtk.Button('Launch') + self.btn_detail = gtk.Button('Details') + self.last_row.pack_start(self.btn_launch,False,False) + self.last_row.pack_end(self.btn_detail,False,False) + + self.table.attach(self.last_row,1,3,2,3,yoptions = 0) + + self.last_row.show_all() + + #connect the buttons + self.btn_detail.connect("clicked",self.controller.show_details,self.tutorial) + self.btn_launch.connect("clicked",self.controller.launch_tutorial,self.tutorial) + + +class MyTutorialDetail(WorkshopDetail): + def __init__(self,tutorial,controller): + WorkshopDetail.__init__(self,tutorial,controller) + + #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) + + self.pack_end(fifth_row,False,False) + self.pack_end(fourth_row,False,False) + + fifth_row.show_all() + fourth_row.show_all() + + #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) + + self.controller.get_categories() + + -- cgit v0.9.1