~flimm/epidermis/icon-theme-bugfix

« back to all changes in this revision

Viewing changes to epidermis/epidermis.py

  • Committer: David D Lowe
  • Date: 2011-01-04 22:50:19 UTC
  • Revision ID: daviddlowe.flimm@gmail.com-20110104225019-uo31kb54cbxjt5vt
Tidy up code with better comments.
Deleted unused functions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/usr/bin/env python2.6
2
2
# -*- encoding: UTF-8 -*-
3
3
# Copyright: David D Lowe (c) 2008-2010
4
 
"""Epidermis
5
 
Epidermis theme manager
6
 
For a description of this application in general, see README.txt"""
7
 
 
8
 
#
9
 
# @author: David D Lowe
10
 
# @package: epidermis
11
 
# @license: GNU GPLv3
12
 
# @copyright: (c) 2008-2009 David D Lowe
13
 
#
14
 
# You can contact David D Lowe by sending him a private message in
15
 
# ubuntuforums.org, his username is flimm.
16
 
# http://ubuntuforums.org/member.php?u=539566
17
 
# You can also find him at launchpad:
18
 
# https://launchpad.net/~flimm
19
4
#
20
5
# This program is free software; you can redistribute it and/or modify
21
6
# it under the terms of the GNU General Public License as published by
80
65
    
81
66
    
82
67
    def delete_event(self, widget=None, event=None, data=None):
83
 
        """When the main widow is closed, this functions quits the application"""
 
68
        """Quit the application"""
84
69
        logger.debug("Window closed, exiting")
85
70
        self.openWindows = []
86
71
        for win in self.controls.win,  self.controls.winCustomise,  self.controls.winReview,  self.controls.winAbout,  self.controls.winApplyChoose:
318
303
    #---Main view: ---#00ue00#ueFFFF---------------------------------
319
304
 
320
305
    def append_skin_to_listStore(self, skin, prepend=False):
321
 
        """Adds the skin object's information to listStoreInstalled for controls.tvThemes, use this function 
322
 
        instead of adding skins manually. This allows the listStoreInstalled format to be changed more flexibally.
 
306
        """Add the skin object's information to listStoreInstalled for controls.tvThemes.
 
307
        
 
308
        Use this function instead of adding skins manually. This allows 
 
309
        the listStoreInstalled format to be changed more flexibally.
 
310
        
323
311
        Use the iNAME, iPIGMENT and iPIGMENT_DIR to retrieve information from the listStore
324
 
        Note: Automatically shows CUSTOM: for custom skins"""
 
312
        
 
313
        Note: Automatically shows CUSTOM: for custom skins
 
314
        
 
315
        """
325
316
        if prepend:
326
317
            funcListStore = self.listStoreInstalled.prepend
327
318
            funcSkin = lambda a1:self.displayedSkins.insert(0, a1)
360
351
        funcSkin(skin)
361
352
    
362
353
    def modify_skin_in_listStore(self, skin, index):
363
 
        """Modifies skin object's information in listStoreInstalled for controls.tvThemes, use this function 
364
 
        instead of modifying listStoreInstalled manually. This allows the ListStore format to be changed 
365
 
        more flexibally.
366
 
        Use the iPIGMENT, iNAME and iPIGMENT_DIR to retrieve information from the listStoreInstalled
367
 
        Note: Automatically shows CUSTOM: for custom skins"""
 
354
        """Modify skin object's information in listStoreInstalled for
 
355
        controls.tvThemes.
 
356
        
 
357
        Use this function instead of modifying listStoreInstalled 
 
358
        manually. This allows the ListStore format to be changed more 
 
359
        flexibally.
 
360
        
 
361
        
 
362
        Use the iPIGMENT, iNAME and iPIGMENT_DIR to retrieve information
 
363
        from the listStoreInstalled
 
364
        
 
365
        Note: Automatically shows CUSTOM: for custom skins
 
366
        
 
367
        """
368
368
        if skin.installationDirectory is None or skin.installationDirectory == "":
369
369
            pigmentDir = MY_DATA_HOME
370
370
        else:
395
395
    
396
396
    def remove_skin_in_listStore(self, index):
397
397
        """Remove skin from self.listStoreInstalled for controls.tvThemes
398
 
        index: index of self.listStoreInstalled"""
 
398
        
 
399
        Keyword arguments:
 
400
        index -- index of self.listStoreInstalled
 
401
        
 
402
        """
399
403
        self.listStoreInstalled.remove(self.listStoreInstalled.get_iter(index))
400
404
        self.displayedSkins.pop(index)
401
405
    
402
406
    def get_skin_from_listStore(self, iterr):
403
407
        """Get Skin object corresponding to self.controls.tvThemes.get_model()'s iterr
404
 
        iterr: iter from self.controls.tvThemes.get_model()"""
 
408
        
 
409
        Keyword arguments:
 
410
        iterr -- iter from self.controls.tvThemes.get_model()
 
411
        
 
412
        """
405
413
        if self.controls.tvThemes.get_model().get_path(iterr) is None:
406
414
            print >> sys.stderr, "self.listStoreInstalled.get_path(iterr) in get_skin_from_listStore returned None"
407
415
            return None
409
417
    
410
418
            
411
419
    def add_skins(self):
412
 
        """Adds the skins found in self.installedPigments["skin"] to self.listStoreInstalled
413
 
        and so display them. listStoreInstalled and displayedSkins will be cleared first.
414
 
        If no skins are installed, displays second page of notebookThemes"""
 
420
        """Add the skins found in self.installedPigments["skin"] to self.listStoreInstalled
 
421
        and so display them.
 
422
        
 
423
        listStoreInstalled and displayedSkins will be cleared first.
 
424
        If no skins are installed, displays second page of notebookThemes
 
425
        
 
426
        """
415
427
        self.listStoreInstalled.clear()
416
428
        self.displayedSkins = []
417
429
        for skin in self.installedPigments["skin"]:
425
437
 
426
438
 
427
439
    def find_and_load_installed_pigments(self):
428
 
        """Fills self.installedPigments and loads the information into the
 
440
        """Fill self.installedPigments and load the information into the
429
441
        treeviewChoose widgets of self.winCustomise
430
 
        It doesn't fill self.listStoreInstalled however, use self.add_skins for that"""
 
442
        
 
443
        It doesn't fill self.listStoreInstalled however, you should 
 
444
        use self.add_skins for that.
 
445
        
 
446
        """
431
447
 
432
448
        handy.require_main_thread()
433
449
 
585
601
        self.listFilterInstalled.refilter()
586
602
            
587
603
    def apply_skin_callback(self, widget, data=None):
588
 
        """Apply button callback: shows controls.winApplyChoose"""
 
604
        """Apply button callback: show controls.winApplyChoose"""
589
605
        handy.require_main_thread()
590
606
        if self.currentSkin.codeName != "":
591
607
            self.controls.winApplyChoose.set_transient_for(self.controls.win)
630
646
    
631
647
    def open_pigment_callback(self, widget, data=None):
632
648
        """Called when user clicks Open in the main view
633
 
        Opens an open file dialog and installs the selected pigments"""
 
649
        Open an open file dialog and installs the selected pigments
 
650
        
 
651
        """
634
652
        handy.require_main_thread()
635
653
        
636
654
        # Open GTK file dialog and get results
657
675
            self.activate_installed()
658
676
    
659
677
    def open_pigment_files(self, filenames):
660
 
        """open .pigment files
661
 
        filenames: list of filenames"""
 
678
        """Open .pigment files
 
679
        
 
680
        Keyword arguments:
 
681
        filenames -- list of filenames
 
682
        
 
683
        """
662
684
        self.controls.labelReview.set_label(_("<b><span size=\"xx-large\">Install pigments</span></b>"))
663
685
        self.controls.btPigmentReviewForward.set_label(gtk.STOCK_GO_FORWARD)
664
686
        # delete all previous columns
895
917
    class ApplySkinThread(threading.Thread):
896
918
        """The thread that is called when applying skin
897
919
        This allows for the skin to be applied without freezing the GUI"""
 
920
        
898
921
        def __init__(self, skin, parent, whichPigments=None):
899
 
            """skin is the Skin object to be applied, parent is the
900
 
            EpidermisApp class, whichPigments is a dictionary that selects
901
 
            which pigments to apply, by default, it selects all the pigments"""
 
922
            """Initialise.
 
923
            
 
924
            Keyword argumetns:
 
925
            skin -- the Skin object to be applied
 
926
            parent -- the EpidermisApp instance
 
927
            whichPigments -- dictionary that selects which pigments to 
 
928
                             apply, by default, it selects all the pigments
 
929
            
 
930
            """
902
931
            self.skin = skin
903
932
            self.parent = parent
904
933
            self.parent.set_isApplying(True)
919
948
            #    print >> sys.stderr, "ApplySkinThread returned an error"
920
949
        
921
950
    def apply_skin(self, skin, whichPigments=None):
922
 
        """apply the skin for the user first, and then system-wide
923
 
        skin: Skin object
924
 
        whichPigments: a dictionary of the pigments to apply, the keys are
925
 
        the pigment types, the values are boolean specifying whether to activate
926
 
        the linked pigment of that type"""
 
951
        """Apply the skin for the user first, and then system-wide.
 
952
        
 
953
        Keyword arguments:
 
954
        skin -- Skin object
 
955
        whichPigments -- a dictionary of the pigments to apply, the keys are
 
956
                         the pigment types, the values are boolean 
 
957
                         specifying whether to activate the linked 
 
958
                         pigment of that type
 
959
        
 
960
        """
927
961
        
928
962
        handy.require_non_main_thread()
929
963
        if whichPigments is None:
979
1013
 
980
1014
    
981
1015
    def refresh_customise_window(self):
982
 
        """Fills in the information in the customise window, based on the 
983
 
        selected entry"""
 
1016
        """Fill in the information in the customise window, based on the 
 
1017
        selected entry
 
1018
        
 
1019
        """
984
1020
        handy.require_main_thread()
985
1021
        
986
1022
        # - self.customiseOriginalSkin is a Skin object containing the original
1093
1129
        self.currentSkin.installationDirectory = self.selectedOriginalSkin.installationDirectory
1094
1130
    
1095
1131
    def get_is_customised(self):
1096
 
        """returns whether the skin has been customised"""
 
1132
        """Return whether the skin has been customised"""
1097
1133
        
1098
1134
        handy.require_main_thread()
1099
1135
        if self.currentSkin.codeName == self.CUSTOMISED_SKIN:
1125
1161
        return False
1126
1162
            
1127
1163
    def customise_toggled(self, cell, path, pigmentType):
1128
 
        """callback for the treeviews of the customisation window
1129
 
        toggles the checkbox and then calls self.customise_changed_callback"""
 
1164
        """Callback for the treeviews of the customisation window.
 
1165
        Toggle the checkbox and then calls self.customise_changed_callback
 
1166
        
 
1167
        """
1130
1168
        handy.require_main_thread()
1131
1169
        # toggle
1132
1170
        tv = self.wTree.get_widget("treeviewChoose" + pigmentType.capitalize())
1167
1205
    def customise_changed_callback(self, widget, type):
1168
1206
        """called whenever something changes in the customise window
1169
1207
        This is the function that automatically addes a customised skin or
1170
 
        removes it"""
 
1208
        removes it
 
1209
        
 
1210
        """
1171
1211
        handy.require_main_thread()
1172
1212
        self.wTree.get_widget("textviewCustomiseDescription").get_buffer().set_modified(False)
1173
1213
        # get information from the window
1307
1347
        It used for pigment management (installation and uninstallation, repo)"""
1308
1348
        
1309
1349
        def __init__(self, pigmentType, installed_toggled=None, treeView=None):
1310
 
            """pigmentType: string of the pigmentType
1311
 
            installed_toggled: function to be called when items are ticked or unticked
1312
 
            treeView: the attached treeView for this data"""
 
1350
            """Initialise.
 
1351
            
 
1352
            Keyword arguments:
 
1353
            pigmentType -- string of the pigmentType
 
1354
            installed_toggled -- function to be called when items are ticked or unticked
 
1355
            treeView -- the attached treeView for this data
 
1356
            
 
1357
            """
1313
1358
            self.pigmentType = pigmentType
1314
1359
            self.treeView = treeView
1315
1360
            self.pigments = []
1341
1386
                self.treeView.append_column(col)
1342
1387
        
1343
1388
        def get_pigmentType(self):
1344
 
            """returns the pigmentType string"""
 
1389
            """Return the pigmentType string"""
1345
1390
            return self.pigmentType
1346
1391
        
1347
1392
        def get_listStore(self):
1348
 
            """returns the object's listStore"""
 
1393
            """Return the object's listStore"""
1349
1394
            return self.listStoreInstalled
1350
1395
        
1351
1396
        def get_columns(self):
1352
 
            """returns the object's columns"""
 
1397
            """Return the object's columns"""
1353
1398
            return self.columns
1354
1399
        
1355
1400
        def get_treeView(self):
1356
 
            """returns the object's treeView"""
 
1401
            """Return the object's treeView"""
1357
1402
            return self.treeView
1358
1403
        
1359
1404
        def append_to_listStore(self, pigment, installed=False, listStore=None):
1360
 
            """append to listStore the information, if listStore is not specified,
1361
 
            self's listStore is used"""
 
1405
            """Append to listStore the information, if listStore is not specified,
 
1406
            self's listStore is used.
 
1407
            
 
1408
            """
1362
1409
            if listStore is None:
1363
1410
                listStore = self.listStoreInstalled
1364
1411
            if pigment.type.codeName != self.pigmentType:
1379
1426
                raise(ee)
1380
1427
        
1381
1428
        def get_installed(self, itemNumber, listStore=None):
1382
 
            """Returns whether the Pigment object referenced by itemNumber is 
1383
 
            installed according to this object's memory"""
 
1429
            """Return whether the Pigment object referenced by itemNumber is 
 
1430
            installed according to this object's memory
 
1431
            
 
1432
            """
1384
1433
            if listStore is None:
1385
1434
                listStore = self.listStoreInstalled
1386
1435
            item = listStore[itemNumber]
1404
1453
        
1405
1454
        
1406
1455
        def get_dependancies(self,itemNumber):
1407
 
            """Returns dependancies in a dictionary format, example:
1408
 
            {"gdm":"codeName1", "metacity":"codeName2", ...}"""
 
1456
            """Return dependancies in a dictionary format.
 
1457
            
 
1458
            Example:
 
1459
            {"gdm":"codeName1", "metacity":"codeName2", ...}
 
1460
            
 
1461
            """
1409
1462
            depends = {}
1410
1463
            for pt in self.pigments[itemNumber].linkedPigments:
1411
1464
                if pt in const.PIGMENT_TYPES[1:]:
1413
1466
            return depends
1414
1467
        
1415
1468
        def __ct_toggled(self, cell, path):
1416
 
            """provides ticking and unticking functionality"""
 
1469
            """Provide ticking and unticking functionality"""
1417
1470
            self.listStoreInstalled[path][6] = not self.listStoreInstalled[path][6]
1418
1471
            self.installed_toggled(cell,path, self.pigmentType)
1419
1472
            return
1423
1476
        
1424
1477
    
1425
1478
    def set_isApplying(self, isApplying):
1426
 
        """sets isApplying. isApplying is used to stop two skins being applied
1427
 
        at once"""
 
1479
        """Sets isApplying.
 
1480
        
 
1481
        isApplying is used to stop two skins being applied at once.
 
1482
        
 
1483
        """
1428
1484
        handy.require_main_thread()
1429
1485
        self.isApplying = isApplying
1430
1486
        modThemes, iterr = self.controls.tvThemes.get_selection().get_selected()
1470
1526
 
1471
1527
       
1472
1528
    def load_repo(self):
1473
 
        """loads repo into the appropriate TreeView widgets, downloads repo
 
1529
        """Load repo into the appropriate TreeView widgets, downloads repo
1474
1530
        information if necessary"""
1475
1531
        loadrepo.load_repo(self)
1476
1532
 
1516
1572
        managepigments.manage_repo_pigments(self,installDict,removeDict)
1517
1573
    
1518
1574
    def is_pigment_installed(self, pigmentType, pigment):
1519
 
        """returns whether epidermis pigment is installed"""
 
1575
        """Return whether epidermis pigment is installed"""
1520
1576
        if os.path.exists(os.path.join(MY_DATA_HOME, get_dirname(pigmentType),pigment, "pigment.xml")):
1521
1577
            return True
1522
1578
        elif os.path.exists(os.path.join(const.SHARED_PIGMENT_DIR, get_dirname(pigmentType), pigment, "pigment.xml")):
1527
1583
    def installed_toggled(self, cell, path, pigmentType):
1528
1584
        """called whenever a epidermis pigment in repository browser is ticked
1529
1585
        or unticked. It automatically ticks dependencies of newly ticked shemes, 
1530
 
        and automatically unticks dependant skins of newly ticked epidermis pigments"""
 
1586
        and automatically unticks dependant skins of newly ticked epidermis pigments
 
1587
        
 
1588
        """
1531
1589
        handy.require_main_thread()
1532
1590
        if pigmentType == "skin":
1533
1591
            # automatically tick any of the skin's dependancies
1613
1671
    #---Other:---#00ue00#ueFFFF------------------------------------------------------
1614
1672
    
1615
1673
    def messagebox(self, text=None, type=gtk.MESSAGE_INFO, parent=None, secondaryText=""):
1616
 
        """Displays a modal message box with the message and blocks until user
 
1674
        """Display a modal message box with the message and blocks until user
1617
1675
        clicks OK.
1618
 
        Please use this from the gtk.main thread"""
 
1676
        Please use this from the gtk.main thread
 
1677
        
 
1678
        """
1619
1679
        handy.require_main_thread()
1620
1680
        if parent is None:
1621
1681
            dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, type, gtk.BUTTONS_OK, text)
1634
1694
        dialog.destroy()
1635
1695
    
1636
1696
    def questionbox(self, text, parent=None):
1637
 
        """Displays a modal message box with Yes/No buttons and blocks until user
 
1697
        """Display a modal message box with Yes/No buttons and blocks until user
1638
1698
        clicks OK.
 
1699
        
1639
1700
        Please use this from the gtk.main thread
1640
 
        Returns response (gtk.RESPONSE_YES, gtk.RESPONSE_NO or cancel)"""
 
1701
        
 
1702
        Returns response (gtk.RESPONSE_YES, gtk.RESPONSE_NO or cancel)
 
1703
        
 
1704
        """
1641
1705
        handy.require_main_thread()
1642
1706
        if parent is None:
1643
1707
            dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION,
1652
1716
        return res
1653
1717
    
1654
1718
    def show_error(self, text="", secondaryText=None, terminalText=None, parent="$DEFAULTVAR$"):
1655
 
        """displays an error alert box using messagebox() and prints to sys.stderr"""
 
1719
        """Display an error alert box using messagebox() and print to sys.stderr"""
1656
1720
        if parent=="$DEFAULTVAR$":
1657
1721
            parent = self.controls.win
1658
1722
        if terminalText is None:
1662
1726
    
1663
1727
    
1664
1728
    def handle_uncaught_error(self, error):
1665
 
        """?"""
1666
1729
        self.messagebox("Uncaught Error", gtk.MESSAGE_ERROR, self.controls.win, str(error))
1667
1730
 
1668
1731
class UndoCloseWindow:
1726
1789
 
1727
1790
 
1728
1791
def start(args=None):
1729
 
    """starts the application"""
 
1792
    """Start the application"""
1730
1793
    assert not None in (const.CACHE_HOME, const.CONFIG_HOME, const.DATA_HOME)
1731
1794
    
1732
1795
    # i18n stuff
1793
1856
 
1794
1857
 
1795
1858
def determine_path ():
1796
 
    """returns the path of this .py file (just the directory)
 
1859
    """Return the path of this .py file (just the directory)
1797
1860
    Borrowed from wxglade.py"""
1798
1861
    try:
1799
1862
        root = __file__
1808
1871
 
1809
1872
 
1810
1873
def get_dirname(singular):
1811
 
    """Turns nouns into the corresponding directory found in dataHome +
 
1874
    """Turn nouns into the corresponding directory found in dataHome +
1812
1875
    \"epidermis/\"
1813
1876
    Eg: wallpaper into wallpapers, gdm into gdm"""
1814
1877
    return managepigments.get_pigment_type(singular).directoryName
1815
1878
 
1816
1879
def main():
1817
 
    """launches start(sys.argv)"""
 
1880
    """Launch start(sys.argv)"""
1818
1881
    start(sys.argv)
1819
1882
 
1820
1883
if __name__ == "__main__":