예제 #1
0
 def __init__(self):
     '''
     一些初始设置
     '''
     super().__init__()
     self.m_pModel = ListModel()
     self.setModel(self.m_pModel)
예제 #2
0
 def __init__(self, username, client_id, client_secret, redirect_url,user):
     super(SpotipyModule, self).__init__()
     # initalizes variables
     self.username = username
     self.client_id = client_id
     self.client_secret = client_secret
     self.redirect_url = redirect_url
     self.scope = 'user-library-read user-read-playback-state streaming' \
                  ' playlist-modify-public user-modify-playback-state playlist-modify-private ' \
                  'user-read-playback-position user-read-currently-playing user-read-private'
     self.user = user
     self.spellchecker = spellchecker.SpellChecker(language=u'en', distance=2)
     self.queue_id = None
     self.playing = False
     self.queue_uri = None
     self.queue_changed = False
     self.current_queue = None
     self.playlist_ids = None
     self.playlist_names = None
     self.search_results = None
     self.dur_time = 0
     self.artist = ""
     self.title = ""
     self.picture = qtc.QUrl()
     self.search_list = ListModel(SpotipyModule.SongWrapper)
     self.token = self.generate_token()
     self.queue = self.generate_queue()
     self.devices = self.token.devices()
예제 #3
0
class Backlinks(Gramplet):
    """
    Displays the back references for an object.
    """
    def init(self):
        self.gui.WIDGET = self.build_gui()
        self.gui.get_container_widget().remove(self.gui.textview)
        self.gui.get_container_widget().add(self.gui.WIDGET)
        self.gui.WIDGET.show()

    def build_gui(self):
        """
        Build the GUI interface.
        """
        top = gtk.TreeView()
        titles = [
            (_('Type'), 1, 100),
            (_('Name'), 2, 100),
            ('', 3, 1),  #hidden column for the handle
            ('', 4, 1)
        ]  #hidden column for non-localized object type
        self.model = ListModel(top, titles, event_func=self.cb_double_click)
        return top

    def display_backlinks(self, active_handle):
        """
        Display the back references for an object.
        """
        for classname, handle in \
                        self.dbstate.db.find_backlink_handles(active_handle):
            name = navigation_label(self.dbstate.db, classname, handle)[0]
            self.model.add((_(classname), name, handle, classname))
        self.set_has_data(self.model.count > 0)

    def get_has_data(self, active_handle):
        """
        Return True if the gramplet has data, else return False.
        """
        if active_handle is None:
            return False
        for handle in self.dbstate.db.find_backlink_handles(active_handle):
            return True
        return False

    def cb_double_click(self, treeview):
        """
        Handle double click on treeview.
        """
        (model, iter_) = treeview.get_selection().get_selected()
        if not iter_:
            return

        (objclass, handle) = (model.get_value(iter_,
                                              3), model.get_value(iter_, 2))

        edit_object(self.dbstate, self.uistate, objclass, handle)
예제 #4
0
    def _create_dialog(self):
        """
        Create a dialog box to organize tags.
        """
        # pylint: disable-msg=E1101
        title = _("%(title)s - Gramps") % {'title': _("Organize Tags")}
        top = gtk.Dialog(title)
        top.set_default_size(400, 350)
        top.set_modal(True)
        top.set_transient_for(self.parent_window)
        top.set_has_separator(False)
        top.vbox.set_spacing(5)
        label = gtk.Label('<span size="larger" weight="bold">%s</span>' %
                          _("Organize Tags"))
        label.set_use_markup(True)
        top.vbox.pack_start(label, 0, 0, 5)
        box = gtk.HBox()
        top.vbox.pack_start(box, 1, 1, 5)

        name_titles = [
            ('', NOSORT, 20, INTEGER),  # Priority
            ('', NOSORT, 100),  # Handle
            (_('Name'), NOSORT, 200),
            (_('Color'), NOSORT, 50, COLOR)
        ]
        self.namelist = gtk.TreeView()
        self.namemodel = ListModel(self.namelist, name_titles)

        slist = gtk.ScrolledWindow()
        slist.add_with_viewport(self.namelist)
        slist.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        box.pack_start(slist, 1, 1, 5)
        bbox = gtk.VButtonBox()
        bbox.set_layout(gtk.BUTTONBOX_START)
        bbox.set_spacing(6)
        up = gtk.Button(stock=gtk.STOCK_GO_UP)
        down = gtk.Button(stock=gtk.STOCK_GO_DOWN)
        add = gtk.Button(stock=gtk.STOCK_ADD)
        edit = gtk.Button(stock=gtk.STOCK_EDIT)
        remove = gtk.Button(stock=gtk.STOCK_REMOVE)
        up.connect('clicked', self.cb_up_clicked)
        down.connect('clicked', self.cb_down_clicked)
        add.connect('clicked', self.cb_add_clicked, top)
        edit.connect('clicked', self.cb_edit_clicked, top)
        remove.connect('clicked', self.cb_remove_clicked, top)
        top.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
        top.add_button(gtk.STOCK_HELP, gtk.RESPONSE_HELP)
        bbox.add(up)
        bbox.add(down)
        bbox.add(add)
        bbox.add(edit)
        bbox.add(remove)
        box.pack_start(bbox, 0, 0, 5)
        top.show_all()
        return top
예제 #5
0
 def build_gui(self):
     """
     Build the GUI interface.
     """
     top = gtk.TreeView()
     titles = [(_('Type'), 0, 100),
               (_('Name'), 1, 100),
               ('', 2, 1), #hidden column for the handle
               ('', 3, 1)] #hidden column for non-localized object type
     self.model = ListModel(top, titles, event_func=self.cb_double_click)
     return top
예제 #6
0
 def build_gui(self):
     """
     Build the GUI interface.
     """
     tip = _('Double-click on a row to view a quick report showing '
             'all people with the selected attribute.')
     self.set_tooltip(tip)
     top = gtk.TreeView()
     titles = [(_('Key'), 1, 100), (_('Value'), 2, 100)]
     self.model = ListModel(top, titles, event_func=self.display_report)
     return top
예제 #7
0
 def build_gui(self):
     """
     Build the GUI interface.
     """
     tip = _('Double-click on a row to edit the selected event.')
     self.set_tooltip(tip)
     top = gtk.TreeView()
     titles = [('', NOSORT, 50,),
               (_('Date'), 1, 200),
               (_('Place'), 2, 200)]
     self.model = ListModel(top, titles, event_func=self.edit_event)
     return top
예제 #8
0
class Attributes(Gramplet):
    """
    Displays the attributes of an object.
    """
    def init(self):
        self.gui.WIDGET = self.build_gui()
        self.gui.get_container_widget().remove(self.gui.textview)
        self.gui.get_container_widget().add(self.gui.WIDGET)
        self.gui.WIDGET.show()

    def build_gui(self):
        """
        Build the GUI interface.
        """
        tip = _('Double-click on a row to view a quick report showing '
                'all people with the selected attribute.')
        self.set_tooltip(tip)
        top = gtk.TreeView()
        titles = [(_('Key'), 1, 100), (_('Value'), 2, 100)]
        self.model = ListModel(top, titles, event_func=self.display_report)
        return top

    def display_attributes(self, obj):
        """
        Display the attributes of an object.
        """
        for attr in obj.get_attribute_list():
            self.model.add((attr.get_type(), attr.get_value()))
        self.set_has_data(self.model.count > 0)

    def display_report(self, treeview):
        """
        Display the quick report for matching attribute key.
        """
        model, iter_ = treeview.get_selection().get_selected()
        if iter_:
            key = model.get_value(iter_, 0)
            run_quick_report_by_name(self.dbstate, self.uistate,
                                     'attribute_match', key)

    def get_has_data(self, obj):
        """
        Return True if the gramplet has data, else return False.
        """
        if obj is None:
            return False
        if obj.get_attribute_list():
            return True
        return False
예제 #9
0
 def build_gui(self):
     """
     Build the GUI interface.
     """
     tip = _('Double-click on a row to edit the selected child.')
     self.set_tooltip(tip)
     top = gtk.TreeView()
     titles = [('', NOSORT, 50,),
               (_('Child'), 1, 250),
               (_('Birth Date'), 3, 100),
               ('', 3, 100),
               (_('Death Date'), 5, 100),
               ('', 5, 100)]
     self.model = ListModel(top, titles, event_func=self.edit_person)
     return top
예제 #10
0
 def build_gui(self):
     """
     Build the GUI interface.
     """
     tip = _('Double-click on a row to edit the selected event.')
     self.set_tooltip(tip)
     top = gtk.TreeView()
     titles = [(
         '',
         NOSORT,
         50,
     ), (_('Type'), 1, 100), (_('Main Participants'), 2, 200),
               (_('Date'), 4, 100), ('', 4, 100), (_('Place'), 5, 400),
               (_('Description'), 6, 150), (_('Role'), 7, 100)]
     self.model = ListModel(top, titles, event_func=self.edit_event)
     return top
예제 #11
0
    def _create_dialog(self):
        """
        Create a dialog box to select tags.
        """
        # pylint: disable-msg=E1101
        title = _("%(title)s - Gramps") % {'title': _("Edit Tags")}
        top = gtk.Dialog(title)
        top.set_default_size(360, 400)
        top.set_modal(True)
        top.set_has_separator(False)
        top.vbox.set_spacing(5)

        columns = [('', -1, 300), (' ', -1, 25, TOGGLE, True, None),
                   (_('Tag'), -1, 300)]
        view = gtk.TreeView()
        self.namemodel = ListModel(view, columns)

        slist = gtk.ScrolledWindow()
        slist.add_with_viewport(view)
        slist.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        top.vbox.pack_start(slist, 1, 1, 5)

        top.add_button(gtk.STOCK_HELP, gtk.RESPONSE_HELP)
        top.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
        top.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
        top.show_all()
        return top
예제 #12
0
 def build_gui(self):
     """
     Build the GUI interface.
     """
     tip = _('Double-click on a row to edit the selected source/citation.')
     self.set_tooltip(tip)
     top = gtk.TreeView()
     titles = [(
         '',
         NOSORT,
         50,
     ), (_('Source/Citation'), 1, 350), (_('Author'), 2, 200),
               (_('Publisher'), 3, 150)]
     self.model = ListModel(top,
                            titles,
                            list_mode="tree",
                            event_func=self.invoke_editor)
     return top
예제 #13
0
 def build_gui(self):
     """
     Build the GUI interface.
     """
     top = gtk.TreeView()
     titles = [(_('Type'), 0, 100),
               (_('Name'), 1, 100),
               ('', 2, 1), #hidden column for the handle
               ('', 3, 1)] #hidden column for non-localized object type
     self.model = ListModel(top, titles, event_func=self.cb_double_click)
     return top
예제 #14
0
class ListView(QListView):
    def __init__(self, parent):
        super().__init__(parent=parent)
        self.m_pModel = ListModel([])
        self.setModel(self.m_pModel)

    def contextMenuEvent(self, event):
        hitIndex = self.indexAt(event.pos()).column()
        if hitIndex > -1:
            pmenu = QMenu(self)
            pDownloadAct = QAction(QIcon('logo.jpg'), "抓取微博", pmenu)
            pmenu.addAction(pDownloadAct)
            pDownloadAct.triggered.connect(self.doScrapy)
            pOpenMenu = QAction(QIcon('logo.jpg'), "在浏览器中打开", pmenu)
            pmenu.addAction(pOpenMenu)

            pOpenMenu.triggered.connect(self.openInBrowser)

            pmenu.popup(self.mapToGlobal(event.pos()))

    def clearData(self):
        self.m_pModel = ListModel([])
        self.setModel(self.m_pModel)

    def openInBrowser(self):
        index = self.currentIndex().row()
        url = "https://weibo.com/u/{}".format(
            self.m_pModel.getItem(index).get('uid'))
        print(url)
        webbrowser.open(url)

    def doScrapy(self):
        global vgs
        index = self.currentIndex().row()
        vgs.ps.emit(self.m_pModel.getItem(index).get('uid'))
        print(index)

    def addItem(self, pitem):
        self.m_pModel.addItem(pitem)
예제 #15
0
class PersonChildren(Children):
    """
    Displays the children of a person.
    """
    def build_gui(self):
        """
        Build the GUI interface.
        """
        tip = _('Double-click on a row to edit the selected child.')
        self.set_tooltip(tip)
        top = gtk.TreeView()
        titles = [('', NOSORT, 50,),
                  (_('Child'), 1, 250),
                  (_('Birth Date'), 3, 100),
                  ('', 3, 100),
                  (_('Death Date'), 5, 100),
                  ('', 5, 100),
                  (_('Spouse'), 6, 250)]
        self.model = ListModel(top, titles, event_func=self.edit_person)
        return top

    def db_changed(self):
        self.dbstate.db.connect('person-update', self.update)

    def active_changed(self, handle):
        self.update()

    def main(self):
        active_handle = self.get_active('Person')
        self.model.clear()
        if active_handle:
            self.display_person(active_handle)
        else:
            self.set_has_data(False)

    def update_has_data(self):
        active_handle = self.get_active('Person')
        active = self.dbstate.db.get_person_from_handle(active_handle)
        self.set_has_data(self.get_has_data(active))

    def get_has_data(self, active_person):
        """
        Return True if the gramplet has data, else return False.
        """
        if active_person is None:
            return False
        for family_handle in active_person.get_family_handle_list():
            family = self.dbstate.db.get_family_from_handle(family_handle)
            if family.get_child_ref_list():
                return True
        return False

    def display_person(self, active_handle):
        """
        Display the children of the active person.
        """
        active_person = self.dbstate.db.get_person_from_handle(active_handle)
        for family_handle in active_person.get_family_handle_list():
            family = self.dbstate.db.get_family_from_handle(family_handle)
            self.display_family(family, active_handle)
        self.set_has_data(self.model.count > 0)

    def display_family(self, family, active_handle):
        """
        Display the children of given family.
        """
        father_handle = family.get_father_handle()
        mother_handle = family.get_mother_handle()
        if father_handle == active_handle:
            spouse = self.dbstate.db.get_person_from_handle(mother_handle)
        else:
            spouse = self.dbstate.db.get_person_from_handle(father_handle)

        for child_ref in family.get_child_ref_list():
            child = self.dbstate.db.get_person_from_handle(child_ref.ref)
            self.add_child(child, spouse)

    def add_child(self, child, spouse):
        """
        Add a child to the model.
        """
        name = name_displayer.display(child)
        if spouse:
            spouse = name_displayer.display(spouse)
        birth = get_birth_or_fallback(self.dbstate.db, child)
        birth_date, birth_sort, birth_place = self.get_date_place(birth)
        death = get_death_or_fallback(self.dbstate.db, child)
        death_date, death_sort, death_place = self.get_date_place(death)
        self.model.add((child.get_handle(),
                        name,
                        birth_date,
                        birth_sort,
                        death_date,
                        death_sort,
                        spouse))
예제 #16
0
class SpotipyModule(qtc.QObject):

    #Signals
    currTitleChanged = qtc.Signal()
    currArtistChanged = qtc.Signal()
    currIconChanged = qtc.Signal()
    durTimeChanged = qtc.Signal()

    def __init__(self, username, client_id, client_secret, redirect_url,user):
        super(SpotipyModule, self).__init__()
        # initalizes variables
        self.username = username
        self.client_id = client_id
        self.client_secret = client_secret
        self.redirect_url = redirect_url
        self.scope = 'user-library-read user-read-playback-state streaming' \
                     ' playlist-modify-public user-modify-playback-state playlist-modify-private ' \
                     'user-read-playback-position user-read-currently-playing user-read-private'
        self.user = user
        self.spellchecker = spellchecker.SpellChecker(language=u'en', distance=2)
        self.queue_id = None
        self.playing = False
        self.queue_uri = None
        self.queue_changed = False
        self.current_queue = None
        self.playlist_ids = None
        self.playlist_names = None
        self.search_results = None
        self.dur_time = 0
        self.artist = ""
        self.title = ""
        self.picture = qtc.QUrl()
        self.search_list = ListModel(SpotipyModule.SongWrapper)
        self.token = self.generate_token()
        self.queue = self.generate_queue()
        self.devices = self.token.devices()

    # generates access token for authorization to use spotify API
    def generate_token(self):
        token = util.prompt_for_user_token(self.username, self.scope, self.client_id, self.client_secret,
                                           self.redirect_url)
        #returns an authorized Spotify object if token is valid
        if token:
            sp = spy.Spotify(auth=token)
            return sp

    #generates a playlist that acts as a queue
    def generate_queue(self):
        playlists = self.token.user_playlists(self.user)
        #Checks Each Playlist to see if Queue exists
        for playlist in playlists['items']:
            #Sets Class Variables to Current Queue Variables if Queue exists
            if (playlist['name']) == 'Queue':
                self.queue_id = playlist['id']
                self.queue_uri = playlist['uri']
                self.current_queue = self.queue_uri
        #Makes Queue Playlist if not found
        if(self.queue_id is None):
            self.token.user_playlist_create(self.user,'Queue', public=True, description="Queue made by Yours Truly, Jarvis")
            playlists = self.token.user_playlists(self.user)
            self.queue_id = playlists['items'][0]['id']
            self.queue_uri = playlists['items'][0]['uri']
            self.current_queue = self.queue_uri
        return

    '''
    Adds a song to the queue playlist and Obtains title, picture, and artist for QML Display
    Args: str(spotify id of a song)
    '''
    @qtc.Slot(str)
    def add_song_to_queue(self, song_title):
        # search_query = song_title.replace(" ", "&20")
        # print(search_query)

        # Find all songs that show up for this query
        self.search_results = (self.token.search(song_title, 10, 0, type='track,album'))
        self.search_list.clear()

        # loop places song titles into list of possible songs
        for temp in self.search_results['tracks']['items']:
            title = temp['name']
            picture_image = temp['album']['images'][1]['url']
            artist = temp['artists'][0]['name']
            self.search_list.appendRow(SpotipyModule.SongWrapper(title, artist, picture_image, self.search_list))
        return

    '''
    Allows User to Choose a Song Based on Search Results from query.
    Args: Number of Chosen song
    '''
    @qtc.Slot(int)
    def helper_add_song_to_queue(self, number):

        # Change the queue to the default queue
        if self.current_queue != self.queue_uri:
            self.current_queue = self.queue_uri
            self.queue_changed = True

        self.search_list.clear()
        #Obtains specific song Information from Queried Song List based on Number
        temp = self.search_results['tracks']['items'][number]
        song = temp['uri']
        #Adds specifcied song into Playlist
        self.token.user_playlist_add_tracks(self.user, self.queue_id, tracks=[song])
        return

    # Plays Music from Queue Playlist or a Specified Playlist
    @qtc.Slot()
    def play_music(self):
        #Starts Playing Songs in Queue and Sets the current playing song info in Front end
        if(self.playing == False):
            print("Entered")
            self.token.start_playback(context_uri=self.current_queue)
            self.token.shuffle(False)
            time.sleep(.1)
            self.set_current_song_info()


        else:
            # Starts the playback of specified Playlist
            if self.queue_changed:
                self.token.start_playback(context_uri=self.current_queue)
                self.queue_changed = False
            else:
                self.token.start_playback()
            self.token.shuffle(False)

        self.playing = True
        return

    # Pauses music
    @qtc.Slot()
    def pause_music(self):
        self.token.pause_playback()
        return

    #Sets the Current time of the song, Artist, Picture, and Title of the song that is playing
    @qtc.Slot()
    def set_current_song_info(self):
        try:
            #Obtain Current Song Data
            temp = self.token.current_user_playing_track()['item']
            song_title = temp['name']

            #Checks if information is already set
            if(song_title == self.title):
                return
            self.set_durTime(temp['duration_ms'])
            self.set_currArtist(temp['artists'][0]['name'])
            self.set_currIcon(temp['album']['images'][0]['url'])
            self.set_currTitle(song_title)
            return
        # If Spotipy is not playing anything... ie self.token.set_current_song_info = None; return
        except TypeError:
            return

    #Gets the Progression of the Time of the Current Song
    @qtc.Slot(result=int)
    def get_current_time(self):
        #If song is not playing, Time is 0
        if(not self.playing):
            return 0
        songtime = self.token.current_user_playing_track()['progress_ms']
        time.sleep(.03)
        return songtime

    #Returns Title of Current Song
    @qtc.Property(str, notify=currTitleChanged)
    def currTitle(self):
        return self.title

    #Sends Signal when Current Title is Changed
    @currTitle.setter
    def set_currTitle(self, new_title):
        if self.title == new_title:
            return
        self.title = new_title
        self.currTitleChanged.emit()

    #Returns Album/Playlist Cover of Song
    @qtc.Property(qtc.QUrl, notify=currIconChanged)
    def currIcon(self):
        return self.picture

    #Sends Signal when Current Picture is Changed
    @currIcon.setter
    def set_currIcon(self, new_icon):
        if self.picture == new_icon:
            return
        self.picture = new_icon
        self.currIconChanged.emit()

    #Returns Artist of Current Song
    @qtc.Property(qtc.QUrl, notify=currArtistChanged)
    def currArtist(self):
        return self.artist

    #Sends Signal when Current Artist is Changed
    @currArtist.setter
    def set_currArtist(self, new_artist):
        if self.artist == new_artist:
            return
        self.artist = new_artist
        self.currArtistChanged.emit()

    #Returns Time of Progress of Song in seconds
    @qtc.Property(float, notify=durTimeChanged)
    def durTime(self):
        if self.dur_time == 0:
            return 10000
        return self.dur_time

    #Sends Signal when Progression of Song is changed
    @durTime.setter
    def set_durTime(self,time):
        if self.dur_time == time:
            return
        else:
            self.dur_time = time
            self.durTimeChanged.emit()

    # changes volume of current song
    @qtc.Slot(int)
    def change_volume(self, value):
        if self.token.current_user_playing_track() is not None:
            self.token.volume(value)

        return value

    # allows user to start playing in middle of song
    @qtc.Slot(int, result=int)
    def change_time(self, song_time):
        #If User sets a songtime within the time limit, time sets: else, dur_time remains the same
        if song_time >= 0 and song_time < self.dur_time:
            self.token.seek_track(position_ms=song_time)
            return song_time
        elif song_time >= self.dur_time:
            self.token.seek_track(position_ms=self.dur_time)
        else:
            return

    @qtc.Slot()
    # skips current song to next in queue/playlist
    def next_song(self):
        self.token.next_track()
        time.sleep(.1)
        self.set_current_song_info()
        return

    @qtc.Slot()
    # goes back 1 song
    def prev_song(self):
        self.token.previous_track()
        time.sleep(.1)
        self.set_current_song_info()
        return

    '''
    Finds a List of Playlist based on a Query
    Args: Playlist_title: A query for a playlist name
    Returns: A list of playlists that matches closely to query
    '''
    @qtc.Slot(str)
    def find_a_playlist(self, playlist_title):
        #Obtains list of 20 playlist id's
        search_results = self.token.search(playlist_title, 20, 0, 'playlist')
        if len(search_results['playlists']['items']) == 0:
            self.spellchecker.split_words(playlist_title)

        #initalizes list to hold data from each playlist
        playlist_number = 1
        playlist_index = 0
        playlist_to_be_queued = [None] * len(search_results['playlists']['items'])
        playlist_ids = [None] * len(search_results['playlists']['items'])

        # Clear the search list
        self.search_list.clear()
        # Add the playlists to the search list
        for songz in range(0, len(search_results['playlists']['items'])):
            name = str(playlist_number) + ') ' + search_results['playlists']['items'][songz]['name']
            author = search_results['playlists']['items'][songz]['owner']['display_name']
            playlist_ids[playlist_index] = search_results['playlists']['items'][songz]['uri']

            self.search_list.appendRow(SpotipyModule.SongWrapper(name, author, "", self.search_list))
            playlist_number += 1
            playlist_index += 1

        self.playlist_ids = playlist_ids
        self.playlist_names = playlist_to_be_queued
        return self.playlist_ids
    
    # plays songs from a specific playlist
    @qtc.Slot(int)
    def queue_music_from_playlist(self, index):
        
        # Clear the search list
        self.search_list.clear()

        playlist = self.playlist_ids[index]
        self.current_queue = playlist
        self.queue_changed = True
        self.play_music()
        return
        
    def destroyer(self):
        self.token.user_playlist_unfollow(user=self.user, playlist_id=self.queue_id)
        return

    #SongWrapper is a wrapper that wraps an object in a Qt object
    class SongWrapper(qtc.QObject):

        # Dictionary of roles for SongWrapper
        roles = {
            qtc.Qt.UserRole + 1: b'song',
            qtc.Qt.UserRole + 2: b'artist',
            qtc.Qt.UserRole + 3: b'image_url'
        }

        # Signals
        #songChanged = qtc.Signal()
        #artistChanged = qtc.Signal()
        #image_urlChanged = qtc.Signal()

        # Initialize the wrapper
        def __init__(self, song, artist, image_url, parent=None):
            super(SpotipyModule.SongWrapper, self).__init__()
            self._data = {b'song': song, b'artist': artist, b'image_url': image_url}
        
        # Retrieves the given role of the SongWrapper (i.e. song, artist, or image_url)
        def data(self, key):
            return self._data[self.roles[key]]

        @qtc.Property(str)
        def song(self):
            return self._data[b'song']
        
        @qtc.Property(str)
        def artist(self):
            return self._data[b'artist']
        
        @qtc.Property(qtc.QUrl)
        def image_url(self):
            return self._data[b'image_url']

        def __str__(self):
            return "[" + str(self.song) + ", " + str(self.artist)  + "]" 
        
        def __repr__(self):
            return str(self)
예제 #17
0
 def __init__(self):
     gtk.TreeView.__init__(self)
     self.sections = {}
     titles = [(_('Key'), 1, 235), 
       (_('Value'), 2, 325)]
     self.model = ListModel(self, titles, list_mode="tree")
예제 #18
0
class MetadataView(gtk.TreeView):

    def __init__(self):
        gtk.TreeView.__init__(self)
        self.sections = {}
        titles = [(_('Key'), 1, 235), 
          (_('Value'), 2, 325)]
        self.model = ListModel(self, titles, list_mode="tree")

    def display_exif_tags(self, full_path):
        """
        Display the exif tags.
        """
        # pylint: disable=E1101
        self.sections = {}
        self.model.clear()
        if OLD_API: # prior to v0.2.0
            try:
                metadata = pyexiv2.Image(full_path)
            except IOError:
                return False
            metadata.readMetadata()
            for section, key, key2, func in TAGS:
                if key not in metadata.exifKeys():
                    continue

                if func is not None:
                    if key2 is None:
                        human_value = func(metadata[key])
                    else:
                        if key2 in metadata.exifKeys():
                            human_value = func(metadata[key], metadata[key2])
                        else:
                            human_value = func(metadata[key], None)
                else:
                    human_value = metadata.interpretedExifValue(key)
                    if key2 is not None and key2 in metadata.exifKeys():
                        human_value += ' ' + metadata.interpretedExifValue(key2)

                label = metadata.tagDetails(key)[0]
                node = self.__add_section(section)
                self.model.add((label, human_value), node=node)

        else: # v0.2.0 and above
            metadata = pyexiv2.ImageMetadata(full_path)
            try:
                metadata.read()
            except IOError:
                return False
            for section, key, key2, func in TAGS:
                if key not in metadata.exif_keys:
                    continue

                tag = metadata.get(key)
                if key2 is not None and key2 in metadata.exif_keys:
                    tag2 = metadata.get(key2)
                else:
                    tag2 = None

                if func is not None:
                    if key2 is None:
                        human_value = func(tag.value)
                    else:
                        if tag2 is None:
                            human_value = func(tag.value, None)
                        else:
                            human_value = func(tag.value, tag2.value)
                else:
                    human_value = tag.human_value
                    if tag2 is not None:
                        human_value += ' ' + tag2.human_value

                label = tag.label
                node = self.__add_section(section)
                self.model.add((tag.label, human_value), node=node)
                
        self.model.tree.expand_all()
        return self.model.count > 0

    def __add_section(self, section):
        """
        Add the section heading node to the model.
        """
        if section not in self.sections:
            node = self.model.add([section, ''])
            self.sections[section] = node
        else:
            node = self.sections[section]
        return node

    def get_has_data(self, full_path):
        """
        Return True if the gramplet has data, else return False.
        """
        # pylint: disable=E1101
        if OLD_API: # prior to v0.2.0
            try:
                metadata = pyexiv2.Image(full_path)
            except IOError:
                return False
            metadata.readMetadata()
            for tag in TAGS:
                if tag[1] in metadata.exifKeys():
                    return True

        else: # v0.2.0 and above
            metadata = pyexiv2.ImageMetadata(full_path)
            try:
                metadata.read()
            except IOError:
                return False
            for tag in TAGS:
                if tag[1] in metadata.exif_keys:
                    return True

        return False
예제 #19
0
class PersonResidence(Gramplet):
    """
    Displays residence events for a person.
    """
    def init(self):
        self.gui.WIDGET = self.build_gui()
        self.gui.get_container_widget().remove(self.gui.textview)
        self.gui.get_container_widget().add(self.gui.WIDGET)
        self.gui.WIDGET.show()

    def build_gui(self):
        """
        Build the GUI interface.
        """
        tip = _('Double-click on a row to edit the selected event.')
        self.set_tooltip(tip)
        top = gtk.TreeView()
        titles = [('', NOSORT, 50,),
                  (_('Date'), 1, 200),
                  (_('Place'), 2, 200)]
        self.model = ListModel(top, titles, event_func=self.edit_event)
        return top
        
    def db_changed(self):
        self.dbstate.db.connect('person-update', self.update)

    def active_changed(self, handle):
        self.update()

    def update_has_data(self):
        active_handle = self.get_active('Person')
        active = self.dbstate.db.get_person_from_handle(active_handle)
        self.set_has_data(self.get_has_data(active))

    def get_has_data(self, active_person):
        """
        Return True if the gramplet has data, else return False.
        """
        if active_person:
            for event_ref in active_person.get_event_ref_list():
                if int(event_ref.get_role()) == EventRoleType.PRIMARY:
                    event = self.dbstate.db.get_event_from_handle(event_ref.ref)
                    if int(event.get_type()) == EventType.RESIDENCE:
                        return True
        return False

    def main(self): # return false finishes
        active_handle = self.get_active('Person')
        active_person = self.dbstate.db.get_person_from_handle(active_handle)
            
        self.model.clear()
        if active_person:
            self.display_person(active_person)
        else:
            self.set_has_data(False)

    def display_person(self, active_person):
        """
        Display the residence events of the active person.
        """
        count = 0
        for event_ref in active_person.get_event_ref_list():
            if int(event_ref.get_role()) == EventRoleType.PRIMARY:
                event = self.dbstate.db.get_event_from_handle(event_ref.ref)
                if int(event.get_type()) == EventType.RESIDENCE:
                    self.add_residence(event)
                    count += 1
        self.set_has_data(count > 0)

    def add_residence(self, event):
        """
        Add a residence event to the model.
        """
        date = DateHandler.get_date(event)
        place = ''
        handle = event.get_place_handle()
        if handle:
            place = self.dbstate.db.get_place_from_handle(handle).get_title()
        self.model.add((event.get_handle(), date, place))

    def edit_event(self, treeview):
        """
        Edit the selected event.
        """
        model, iter_ = treeview.get_selection().get_selected()
        if iter_:
            handle = model.get_value(iter_, 0)
            try:
                event = self.dbstate.db.get_event_from_handle(handle)
                EditEvent(self.dbstate, self.uistate, [], event)
            except Errors.WindowActiveError:
                pass
예제 #20
0
 def __init__(self):
     super().__init__()
     self.m_pModel = ListModel()
     self.setModel(self.m_pModel)
예제 #21
0
    def __init__(self, uistate, track, addon_update_list):
        self.title = _('Available Gramps Updates for Addons')
        ManagedWindow.ManagedWindow.__init__(self, uistate, track,
                                             self.__class__)

        glade = Glade("updateaddons.glade")
        self.update_dialog = glade.toplevel
        self.set_window(self.update_dialog, glade.get_object('title'),
                        self.title)
        self.window.set_size_request(750, 400)

        apply_button = glade.get_object('apply')
        cancel_button = glade.get_object('cancel')
        select_all = glade.get_object('select_all')
        select_all.connect("clicked", self.select_all_clicked)
        select_none = glade.get_object('select_none')
        select_none.connect("clicked", self.select_none_clicked)
        apply_button.connect("clicked", self.install_addons)
        cancel_button.connect("clicked", self.close)

        self.list = ListModel(
            glade.get_object("list"),
            [
                # name, click?, width, toggle
                {
                    "name": _('Select'),
                    "width": 60,
                    "type": TOGGLE,
                    "visible_col": 6,
                    "editable": True
                },  # 0 selected?
                (_('Type'), 1, 180),  # 1 new gramplet
                (_('Name'), 2, 200),  # 2 name (version)
                (_('Description'), 3, 200),  # 3 description
                ('', NOSORT, 0),  # 4 url
                ('', NOSORT, 0),  # 5 id
                {
                    "name": '',
                    "type": TOGGLE
                },  # 6 visible? bool
            ],
            list_mode="tree")
        pos = None
        addon_update_list.sort(key=lambda x: "%s %s" % (x[0], x[2]["t"]))
        last_category = None
        for (status, plugin_url, plugin_dict) in addon_update_list:
            count = get_count(addon_update_list, plugin_dict["t"])
            category = _("%(adjective)s: %(addon)s") % {
                "adjective": status,
                "addon": _(plugin_dict["t"])
            }
            if last_category != category:
                last_category = category
                node = self.list.add([
                    False,  # initially selected?
                    category,
                    "",
                    "",
                    "",
                    "",
                    False
                ])  # checkbox visible?
            iter = self.list.add(
                [
                    False,  # initially selected?
                    "%s %s" % (status, _(plugin_dict["t"])),
                    "%s (%s)" % (plugin_dict["n"], plugin_dict["v"]),
                    plugin_dict["d"],
                    plugin_url,
                    plugin_dict["i"],
                    True
                ],
                node=node)
            if pos is None:
                pos = iter
        if pos:
            self.list.selection.select_iter(pos)
        self.update_dialog.run()
예제 #22
0
 def __init__(self, parent):
     super().__init__(parent=parent)
     self.m_pModel = ListModel([])
     self.setModel(self.m_pModel)
예제 #23
0
class Events(Gramplet, DbGUIElement):
    def __init__(self, gui, nav_group=0):
        Gramplet.__init__(self, gui, nav_group)
        DbGUIElement.__init__(self, self.dbstate.db)

    """
    Displays the events for a person or family.
    """

    def init(self):
        self.gui.WIDGET = self.build_gui()
        self.gui.get_container_widget().remove(self.gui.textview)
        self.gui.get_container_widget().add(self.gui.WIDGET)
        self.gui.WIDGET.show()

    def _connect_db_signals(self):
        """
        called on init of DbGUIElement, connect to db as required.
        """
        self.callman.register_callbacks({'event-update': self.changed})
        self.callman.connect_all(keys=['event'])

    def changed(self, handle):
        """
        Called when a registered event is updated.
        """
        self.update()

    def build_gui(self):
        """
        Build the GUI interface.
        """
        tip = _('Double-click on a row to edit the selected event.')
        self.set_tooltip(tip)
        top = gtk.TreeView()
        titles = [(
            '',
            NOSORT,
            50,
        ), (_('Type'), 1, 100), (_('Main Participants'), 2, 200),
                  (_('Date'), 4, 100), ('', 4, 100), (_('Place'), 5, 400),
                  (_('Description'), 6, 150), (_('Role'), 7, 100)]
        self.model = ListModel(top, titles, event_func=self.edit_event)
        return top

    def add_event_ref(self, event_ref, spouse=None):
        """
        Add an event to the model.
        """
        self.callman.register_handles({'event': [event_ref.ref]})
        event = self.dbstate.db.get_event_from_handle(event_ref.ref)
        event_date = DateHandler.get_date(event)
        event_sort = '%012d' % event.get_date_object().get_sort_value()
        place = ''
        handle = event.get_place_handle()
        if handle:
            place = self.dbstate.db.get_place_from_handle(handle).get_title()

        participants = ''
        if int(event_ref.get_role()) == EventRoleType.FAMILY:
            if spouse:
                participants = name_displayer.display(spouse)

        participants = Utils.get_participant_from_event(
            self.dbstate.db, event_ref.ref)

        self.model.add((event.get_handle(), str(event.get_type()),
                        participants, event_date, event_sort, place,
                        event.get_description(), str(event_ref.get_role())))

    def edit_event(self, treeview):
        """
        Edit the selected event.
        """
        model, iter_ = treeview.get_selection().get_selected()
        if iter_:
            handle = model.get_value(iter_, 0)
            try:
                event = self.dbstate.db.get_event_from_handle(handle)
                EditEvent(self.dbstate, self.uistate, [], event)
            except Errors.WindowActiveError:
                pass
예제 #24
0
class Citations(Gramplet, DbGUIElement):
    def __init__(self, gui, nav_group=0):
        Gramplet.__init__(self, gui, nav_group)
        DbGUIElement.__init__(self, self.dbstate.db)

    """
    Displays the citations for an object.
    """

    def init(self):
        self.gui.WIDGET = self.build_gui()
        self.gui.get_container_widget().remove(self.gui.textview)
        self.gui.get_container_widget().add(self.gui.WIDGET)
        self.gui.WIDGET.show()

    def _connect_db_signals(self):
        """
        called on init of DbGUIElement, connect to db as required.
        """
        self.callman.register_callbacks({'citation-update': self.changed})
        self.callman.connect_all(keys=['citation'])

    def changed(self, handle):
        """
        Called when a registered citation is updated.
        """
        self.update()

    def build_gui(self):
        """
        Build the GUI interface.
        """
        tip = _('Double-click on a row to edit the selected source/citation.')
        self.set_tooltip(tip)
        top = gtk.TreeView()
        titles = [(
            '',
            NOSORT,
            50,
        ), (_('Source/Citation'), 1, 350), (_('Author'), 2, 200),
                  (_('Publisher'), 3, 150)]
        self.model = ListModel(top,
                               titles,
                               list_mode="tree",
                               event_func=self.invoke_editor)
        return top

    def add_citations(self, obj):
        for citation_handle in obj.get_citation_list():
            self.add_citation_ref(citation_handle)

    def add_name_citations(self, obj):
        names = [obj.get_primary_name()] + obj.get_alternate_names()
        for name in names:
            self.add_citations(name)

    def add_attribute_citations(self, obj):
        for attr in obj.get_attribute_list():
            self.add_citations(attr)

    def add_mediaref_citations(self, obj):
        for media_ref in obj.get_media_list():
            self.add_citations(media_ref)
            self.add_attribute_citations(media_ref)
            media = self.dbstate.db.get_object_from_handle(media_ref.ref)
            self.add_media_citations(media)

    def add_media_citations(self, media):
        self.add_citations(media)
        self.add_attribute_citations(media)

    def add_eventref_citations(self, obj):
        for event_ref in obj.get_event_ref_list():
            self.add_attribute_citations(event_ref)
            event = self.dbstate.db.get_event_from_handle(event_ref.ref)
            self.add_event_citations(event)

    def add_event_citations(self, event):
        self.add_citations(event)
        self.add_attribute_citations(event)
        self.add_mediaref_citations(event)
        place_handle = event.get_place_handle()
        place = self.dbstate.db.get_place_from_handle(place_handle)
        if place:
            self.add_place_citations(place)

    def add_place_citations(self, place):
        self.add_citations(place)
        self.add_mediaref_citations(place)

    def add_address_citations(self, obj):
        for address in obj.get_address_list():
            self.add_citations(address)

    def add_lds_citations(self, obj):
        for lds in obj.get_lds_ord_list():
            self.add_citations(lds)
            place_handle = lds.get_place_handle()
            place = self.dbstate.db.get_place_from_handle(place_handle)
            if place:
                self.add_place_citations(place)

    def add_association_citations(self, obj):
        for assoc in obj.get_person_ref_list():
            self.add_citations(assoc)

    def add_citation_ref(self, citation_handle):
        """
        Add a citation to the model.
        """
        self.callman.register_handles({'citation': [citation_handle]})
        citation = self.dbstate.db.get_citation_from_handle(citation_handle)
        page = citation.get_page()
        if not page:
            page = _('<No Citation>')
        source_handle = citation.get_reference_handle()
        source = self.dbstate.db.get_source_from_handle(source_handle)
        title = source.get_title()
        author = source.get_author()
        publisher = source.get_publication_info()

        if source_handle not in self.source_nodes:
            node = self.model.add([source_handle, title, author, publisher])
            self.source_nodes[source_handle] = node

        self.model.add([citation_handle, page, '', ''],
                       node=self.source_nodes[source_handle])

    def check_citations(self, obj):
        return True if obj.get_citation_list() else False

    def check_name_citations(self, obj):
        names = [obj.get_primary_name()] + obj.get_alternate_names()
        for name in names:
            if self.check_citations(name):
                return True
        return False

    def check_attribute_citations(self, obj):
        for attr in obj.get_attribute_list():
            if self.check_citations(attr):
                return True
        return False

    def check_mediaref_citations(self, obj):
        for media_ref in obj.get_media_list():
            if self.check_citations(media_ref):
                return True
            if self.check_attribute_citations(media_ref):
                return True
            media = self.dbstate.db.get_object_from_handle(media_ref.ref)
            if self.check_media_citations(media):
                return True
        return False

    def check_media_citations(self, media):
        if self.check_citations(media):
            return True
        if self.check_attribute_citations(media):
            return True
        return False

    def check_eventref_citations(self, obj):
        for event_ref in obj.get_event_ref_list():
            if self.check_attribute_citations(event_ref):
                return True
            event = self.dbstate.db.get_event_from_handle(event_ref.ref)
            if self.check_event_citations(event):
                return True
        return False

    def check_event_citations(self, event):
        if self.check_citations(event):
            return True
        if self.check_attribute_citations(event):
            return True
        if self.check_mediaref_citations(event):
            return True
        place_handle = event.get_place_handle()
        place = self.dbstate.db.get_place_from_handle(place_handle)
        if place and self.check_place_citations(place):
            return True
        return False

    def check_place_citations(self, place):
        if self.check_citations(place):
            return True
        if self.check_mediaref_citations(place):
            return True
        return False

    def check_address_citations(self, obj):
        for address in obj.get_address_list():
            if self.check_citations(address):
                return True
        return False

    def check_lds_citations(self, obj):
        for lds in obj.get_lds_ord_list():
            if self.check_citations(lds):
                return True
            place_handle = lds.get_place_handle()
            place = self.dbstate.db.get_place_from_handle(place_handle)
            if place and self.check_place_citations(place):
                return True
        return False

    def check_association_citations(self, obj):
        for assoc in obj.get_person_ref_list():
            if self.check_citations(assoc):
                return True
        return False

    def invoke_editor(self, treeview):
        """
        Edit the selected source or citation.
        """
        model, iter_ = treeview.get_selection().get_selected()
        if iter_:
            handle = model.get_value(iter_, 0)
            if len(model.get_path(iter_)) == 1:
                self.edit_source(handle)
            else:
                self.edit_citation(handle)

    def edit_source(self, handle):
        """
        Edit the selected source.
        """
        try:
            source = self.dbstate.db.get_source_from_handle(handle)
            EditSource(self.dbstate, self.uistate, [], source)
        except Errors.WindowActiveError:
            pass

    def edit_citation(self, handle):
        """
        Edit the selected citation.
        """
        try:
            citation = self.dbstate.db.get_citation_from_handle(handle)
            source_handle = citation.get_reference_handle()
            source = self.dbstate.db.get_source_from_handle(source_handle)
            EditCitation(self.dbstate, self.uistate, [], citation, source)
        except Errors.WindowActiveError:
            pass
예제 #25
0
class GmailModule(qtc.QObject):
    loaded = qtc.Signal()

    def __init__(self):
        super(GmailModule, self).__init__()
        self.scopes = ['https://mail.google.com/']
        self.time_elapsed = 0
        self.currentEmailList = ListModel(GmailModule.EmailObject)
        self.threadMessages = ListModel(GmailModule.EmailObject)
        #print("Gmail finished")

    # Initializes the gmail widget in the qml file
    @qtc.Slot(int)
    def init_gmail_in_widget(self, parm):
        self.service = self.use_token_pickle_to_get_service()
        self.messages = self.service.users().messages()
        self.message_ids = self.get_list_of_users_message_ids()
        self.label_list = self.get_labels()
        threading.Thread(target=self.get_preview_message_info,
                         args=(parm, )).start()

    '''
    Accesses a file to gain saved credentials
    if no file exists the file is generated and user is asked to put in creds
    '''

    def use_token_pickle_to_get_service(self):
        creds = None
        # The file token.pickle stores the user's access and refresh tokens, and is
        # created automatically when the authorization flow completes for the first
        # time.
        if os.path.exists('token_gmail.pickle'):
            with open('token_gmail.pickle', 'rb') as token:
                creds = pickle.load(token)
        # If there are no (valid) credentials available, let the user log in.
        if not creds or not creds.valid:
            if creds and creds.expired and creds.refresh_token:
                creds.refresh(Request())
            else:
                flow = InstalledAppFlow.from_client_secrets_file(
                    'credentials_gmail.json', self.scopes)
                creds = flow.run_local_server(port=0)
            # Save the credentials for the next run
            with open('token_gmail.pickle', 'wb') as token:
                pickle.dump(creds, token)

        service = build('gmail', 'v1', credentials=creds)

        return service

    @qtc.Slot()
    def get_labels(self):
        results = self.service.users().labels().list(userId='me').execute()

        labels = results.get('labels', [])
        if not labels:
            return
        else:
            label_list = [None] * len(labels)
            label_list_index = 0
            for label in labels:
                label_list[label_list_index] = (label['name'])
                label_list_index += 1
            return label_list

    def get_list_of_users_message_ids(self):
        emails = self.messages.list(userId='me').execute()
        list_of_msg_ids = [None] * len(emails['messages'])
        index = 0
        for email in range(0, len(emails['messages'])):
            list_of_msg_ids[index] = (emails['messages'][email])
            index += 1
        return list_of_msg_ids

    @qtc.Slot(int, result=str)
    def get_message_id(self, i):
        return self.message_ids[i]['id']

    @qtc.Slot(int, result=str)
    def get_label(self, i):
        return self.label_list[i]

    # Takes an integer as an index and retrieves the message's metadata
    @qtc.Slot(int)
    def get_preview_message_info(self, num_messages):
        for index in range(0, num_messages):
            message = self.messages.get(userId='me',
                                        id=self.message_ids[index]['id'],
                                        format='metadata',
                                        metadataHeaders=[
                                            "To", "From", "Subject",
                                            "References", "Message-ID"
                                        ]).execute()
            self.currentEmailList.appendRow(
                GmailModule.EmailObject(sender=self.GetSender(message),
                                        snippet=self.GetSnippet(message),
                                        subject=self.GetSubjectTitle(message),
                                        threadid=self.GetThread(message),
                                        references=self.GetReferences(message),
                                        messageid=self.GetMessageID(message)))
        return

    @qtc.Slot(str, result=str)
    def GetMessage(self, message):
        try:

            try:

                raw_msg = message['payload']['parts'][0]['body']['data']
                msg_str = base64.urlsafe_b64decode(raw_msg.encode('ASCII'))

            #print(msg_str)
            # print ('Message snippet: %s' % message['payload']['body']['data'])

            except KeyError:

                if 'parts' in message['payload'] and 'parts' in message[
                        'payload']['parts'][0]:
                    if 'data' in (message['payload']['parts'][0]['parts'][0]
                                  ['body']):
                        raw_msg = (message['payload']['parts'][0]['parts'][0]
                                   ['body']['data'])
                        msg_str = base64.urlsafe_b64decode(
                            raw_msg.encode('ASCII'))
                    else:
                        raw_msg = (message['payload']['parts'][0]['parts'][0]
                                   ['parts'][0]['body']['data'])
                        msg_str = base64.urlsafe_b64decode(
                            raw_msg.encode('ASCII'))

                elif 'parts' in message['payload'] and 'data' not in message[
                        'payload']['parts'][0]['body']:

                    raw_msg = ((message['payload']['parts'][0]['parts'][1]
                                ['body']['data']))
                    msg_str = base64.urlsafe_b64decode(raw_msg.encode('ASCII'))
                elif 'parts' in message['payload'] and 'data' in (
                        message['payload']['parts'][0]['body']):
                    raw_msg = ((
                        message['payload']['parts'][0]['body']['data']))
                    msg_str = base64.urlsafe_b64decode(raw_msg.encode('ASCII'))
                else:
                    raw_msg = message['payload']['body']['data']
                    msg_str = base64.urlsafe_b64decode(raw_msg.encode('ASCII'))

                return msg_str

            return msg_str
        except apiclient.errors.HttpError:

            return

    @qtc.Slot(str, result=str)
    def GetSender(self, message):
        try:
            for i in range(0, len((message['payload']['headers']))):
                if (message['payload']['headers'][i]['name']) == 'From':
                    sender = ((message['payload']['headers'][i]['value']))
                    return sender
            return
        except apiclient.errors.HttpError:
            return

    @qtc.Slot(str, result=str)
    def GetSubjectTitle(self, message):
        try:
            for i in range(0, len((message['payload']['headers']))):
                if (message['payload']['headers'][i]['name']) == 'Subject':
                    subject = ((message['payload']['headers'][i]['value']))
                    return subject
        except apiclient.errors.HttpError:
            return

    @qtc.Slot(str, result=str)
    def GetSnippet(self, message):
        try:
            snippet = message['snippet']
            return snippet
        except apiclient.errors.HttpError:
            return

    @qtc.Slot(str, result=str)
    def GetThread(self, message):
        try:
            return message['threadId']
        except apiclient.errors.HttpError:
            return

    @qtc.Slot(str, result=str)
    def GetReferences(self, message):
        try:
            for i in range(0, len((message['payload']['headers']))):
                if (message['payload']['headers'][i]['name']) == 'References':
                    references = ((message['payload']['headers'][i]['value']))
                    return references
        except apiclient.errors.HttpError:
            return

    @qtc.Slot(str, result=str)
    def GetMessageID(self, message):
        try:
            for i in range(0, len((message['payload']['headers']))):
                if (message['payload']['headers'][i]['name']) == 'Message-ID':
                    messageID = ((message['payload']['headers'][i]['value']))
                    return messageID
        except apiclient.errors.HttpError:
            return

    @qtc.Slot()
    def ListMessagesMatchingQuery(self, user_id, query=''):

        try:
            response = self.messages.list(userId='me', q=query).execute()
            messages = []
            if 'messages' in response:
                messages.extend(response['messages'])

            while 'nextPageToken' in response:
                page_token = response['nextPageToken']
                response = self.messages.list(userId=user_id,
                                              q=query,
                                              pageToken=page_token).execute()
                messages.extend(response['messages'])

            return messages
        except apiclient.errors.HttpError as error:
            return

    @qtc.Slot(str)
    def get_messages_with_labels(self, label_ids=''):

        try:
            response = self.messages.list(userId='me',
                                          labelIds=label_ids).execute()
            messages = []
            if 'messages' in response:
                messages.extend(response['messages'])

            while 'nextPageToken' in response and len(messages) <= 50:
                page_token = response['nextPageToken']
                response = self.messages.list(userId='me',
                                              labelIds=label_ids,
                                              pageToken=page_token).execute()
                messages.extend(response['messages'])

            # Add the response to the list of emails
            self.currentEmailList.clear()
            i = 0
            while i < 20 and i < len(messages):
                message = self.messages.get(userId='me',
                                            id=messages[i]['id'],
                                            format='metadata',
                                            metadataHeaders=[
                                                "To", "From", "Subject",
                                                "References", "Message-ID"
                                            ]).execute()
                self.currentEmailList.appendRow(
                    GmailModule.EmailObject(
                        sender=self.GetSender(message),
                        snippet=self.GetSnippet(message),
                        subject=self.GetSubjectTitle(message),
                        threadid=self.GetThread(message),
                        references=self.GetReferences(message),
                        messageid=self.GetMessageID(message)))
                i += 1
            return messages
        except apiclient.errors.HttpError as error:
            return

    @qtc.Slot(str)
    def get_messages_from_query(self, query=''):
        try:
            response = self.messages.list(userId='me', maxResults=50,
                                          q=query).execute()
            messages = []
            if 'messages' in response:
                messages.extend(response['messages'])

            while 'nextPageToken' in response:
                page_token = response['nextPageToken']
                response = self.messages.list(userId='me',
                                              q=query,
                                              pageToken=page_token).execute()
                messages.extend(response['messages'])

            self.currentEmailList.clear()
            #print(messages)]
            i = 0
            while i < 10 and i < len(messages):
                message = self.messages.get(userId='me',
                                            id=messages[i]['id'],
                                            format='metadata',
                                            metadataHeaders=[
                                                "To", "From", "Subject",
                                                "References", "Message-ID"
                                            ]).execute()
                self.currentEmailList.appendRow(
                    GmailModule.EmailObject(
                        sender=self.GetSender(message),
                        snippet=self.GetSnippet(message),
                        subject=self.GetSubjectTitle(message),
                        threadid=self.GetThread(message),
                        references=self.GetReferences(message),
                        messageid=self.GetMessageID(message)))
                i += 1
            return

        except apiclient.errors.HttpError as error:
            return

    def list_message_ids(self):
        emails = self.messages.list(userId='me').execute()
        return emails

    def create_email(self, sender, to, subject, message_text, file_dir,
                     filename):
        message = MIMEMultipart()
        message['to'] = to
        message['from'] = sender
        message['subject'] = subject

        msg = MIMEText(message_text)
        message.attach(msg)

        path = os.path.join(file_dir, filename)
        content_type, encoding = mimetypes.guess_type(path)

        if content_type is None or encoding is not None:
            content_type = 'application/octet-stream'
        main_type, sub_type = content_type.split('/', 1)
        if main_type == 'text':
            fp = open(path, 'rb')
            msg = MIMEText(fp.read(), _subtype=sub_type)
            fp.close()
        elif main_type == 'image':
            fp = open(path, 'rb')
            msg = MIMEImage(fp.read(), _subtype=sub_type)
            fp.close()
        elif main_type == 'audio':
            fp = open(path, 'rb')
            msg = MIMEAudio(fp.read(), _subtype=sub_type)
            fp.close()
        else:
            fp = open(path, 'rb')
            msg = MIMEBase(main_type, sub_type)
            msg.set_payload(fp.read())
            fp.close()

        msg.add_header('Content-Disposition', 'attachment', filename=filename)
        message.attach(msg)

        return {'raw': base64.urlsafe_b64encode(message.as_string())}

    @qtc.Slot(str, str, str, str, str, result=dict)
    def create_basic_email(self,
                           sender,
                           to,
                           subject,
                           message_text,
                           ref=None,
                           in_reply=None):
        message = MIMEText(message_text)
        message['to'] = to
        message['from'] = sender
        message['subject'] = subject

        # Add referecena and in reply to headers if they are set
        if (not (ref is None) and not (in_reply is None)):
            message['References'] = ref
            message['In-Reply-To'] = in_reply
            #print(ref)
            #print(in_reply)
        return {'raw': base64.urlsafe_b64encode((message.as_bytes())).decode()}

    @qtc.Slot(str, str, str, str)
    def send_message(self, sender, to, subject, message_text):

        # Return early if there is no sender
        if (sender == "" or sender.isspace() or sender is None):
            return

        premessage = self.create_basic_email(sender, to, subject, message_text)
        try:
            message = (self.messages.send(userId=sender,
                                          body=premessage).execute())

            return message
        except apiclient.errors.HttpError as error:
            print('error')
            return

    def get_thread(self, query=''):
        response = self.service.users().threads().list(userId='me',
                                                       q=query).execute()
        return

    def get_messages_from_a_thread(self, thread_id):
        try:
            response = self.service.users().threads().get(
                userId='me', id=thread_id).execute()
        except:
            return
        all_messages = response['messages']
        result = []
        for message in range(0, len(all_messages)):
            try:
                raw_msg = (all_messages[message]['payload']['parts'][0]['body']
                           ['data'])
            except KeyError:
                raw_msg = all_messages[message]['payload']['body']['data']
                msg_str = self.GetSender(
                    all_messages[message]) + "\n" + base64.urlsafe_b64decode(
                        raw_msg.encode('ASCII')).decode('utf-8')
                result.append(msg_str)
                return result
            msg_str = (base64.urlsafe_b64decode(
                raw_msg.encode())).decode('utf-8')
            result.append(msg_str)
        return result

    @qtc.Slot(int)
    def add_thread_messages(self, index):
        self.threadMessages.clear()
        threadid = self.currentEmailList.get(index, qtc.Qt.UserRole + 9)
        thread_messages = self.get_messages_from_a_thread(threadid)
        if (thread_messages is None):
            return
        for msg in thread_messages:
            self.threadMessages.appendRow(
                GmailModule.EmailObject(sender="",
                                        snippet="",
                                        subject="",
                                        threadid=threadid,
                                        message=msg))

    @qtc.Slot(str, str, str, str, str, str, str, result=str)
    def respond_to_thread(self, thread_id, sender, to, subject, msg_id,
                          references, message_text):

        # Return early if there is no sender
        if (sender == "" or sender.isspace() or sender is None):
            return
        ref = references
        if (references != ""):
            ref = references + " " + msg_id
        else:
            ref = msg_id
        premessage = self.create_basic_email(sender,
                                             to,
                                             subject,
                                             message_text,
                                             ref=ref,
                                             in_reply=msg_id)
        premessage['threadId'] = thread_id
        print("References ", ref)
        print("Message ID ", msg_id)
        print("Subject ", subject)
        try:
            message = (self.messages.send(userId=sender,
                                          body=premessage).execute())

            return message
        except apiclient.errors.HttpError as error:
            print('error')
            return
        return

    @qtc.Slot(int, result=str)
    def get_current_threadid(self, index):
        return self.currentEmailList.get(index, qtc.Qt.UserRole + 9)

    @qtc.Slot(int, result=str)
    def get_current_sender(self, index):
        return self.currentEmailList.get(index, qtc.Qt.UserRole + 4)

    @qtc.Slot(int, result=str)
    def get_current_subject(self, index):
        return self.currentEmailList.get(index, qtc.Qt.UserRole + 6)

    @qtc.Slot(int, result=str)
    def get_current_message_id(self, index):
        return self.currentEmailList.get(index, qtc.Qt.UserRole + 10)

    @qtc.Slot(int, result=str)
    def get_current_references(self, index):
        return self.currentEmailList.get(index, qtc.Qt.UserRole + 11)

    class EmailObject(qtc.QObject):

        # Roles
        roles = {
            qtc.Qt.UserRole + 4: b'sender',
            qtc.Qt.UserRole + 5: b'receiver',
            qtc.Qt.UserRole + 6: b'subject',
            qtc.Qt.UserRole + 7: b'snippet',
            qtc.Qt.UserRole + 8: b'message',
            qtc.Qt.UserRole + 9: b'threadid',
            qtc.Qt.UserRole + 10: b'messageid',
            qtc.Qt.UserRole + 11: b'references'
        }

        # Signals
        senderChanged = qtc.Signal()
        receiverChanged = qtc.Signal()
        subjectChanged = qtc.Signal()
        snippetChanged = qtc.Signal()
        messageChanged = qtc.Signal()
        threadidChanged = qtc.Signal()

        # Initializer for email object
        def __init__(self,
                     sender=None,
                     receiver=None,
                     subject=None,
                     snippet=None,
                     message=None,
                     threadid=None,
                     messageid=None,
                     references=None):
            super(GmailModule.EmailObject, self).__init__()
            self._data = {
                b'sender': sender,
                b'receiver': receiver,
                b'subject': subject,
                b'snippet': snippet,
                b'message': message,
                b'threadid': threadid,
                b'messageid': messageid,
                b'references': references
            }

        # Retrieves the data
        def data(self, key):
            return self._data[self.roles[key]]

        @qtc.Property(str)
        def sender(self):
            self._data[b'sender']

        @qtc.Property(str)
        def receiver(self):
            return self._data[b'receiver']

        @qtc.Property(str)
        def subject(self):
            return self._data[b'subject']

        @qtc.Property(str)
        def snippet(self):
            return self._data[b'snippet']

        @qtc.Property(str)
        def message(self):
            return self._data[b'message']

        @qtc.Property(str)
        def threadid(self):
            return self._data[b'threadid']

        @qtc.Property(str)
        def messageid(self):
            return self._data[b'messageid']

        @qtc.Property(str)
        def references(self):
            return self._data[b'references']

        def __str__(self):
            return "[" + self.sender + " " + self.receiver + " " + self.subject + ']'

        def __repr__(self):
            return str(self)
예제 #26
0
class OrganizeTagsDialog(object):
    """
    A dialog to enable the user to organize tags.
    """
    def __init__(self, db, parent_window):
        self.db = db
        self.parent_window = parent_window
        self.namelist = None
        self.namemodel = None
        self.top = self._create_dialog()

    def run(self):
        """
        Run the dialog and return the result.
        """
        self._populate_model()
        while True:
            response = self.top.run()
            if response == gtk.RESPONSE_HELP:
                GrampsDisplay.help(webpage=WIKI_HELP_PAGE,
                                   section=WIKI_HELP_SEC)
            else:
                break

        # Save changed priority values
        if self.__priorities_changed():
            with DbTxn(_('Change Tag Priority'), self.db) as trans:
                self.__change_tag_priority(trans)

        self.top.destroy()

    def __priorities_changed(self):
        """
        Return True if the tag priorities have changed else return False.
        """
        priorities = [row[0] for row in self.namemodel.model]
        return priorities != range(len(self.namemodel.model))

    def __change_tag_priority(self, trans):
        """
        Change the priority of the tags.  The order of the list corresponds to
        the priority of the tags.  The top tag in the list is the highest
        priority tag.
        """
        for new_priority, row in enumerate(self.namemodel.model):
            if row[0] != new_priority:
                tag = self.db.get_tag_from_handle(row[1])
                if tag:
                    tag.set_priority(new_priority)
                    self.db.commit_tag(tag, trans)

    def _populate_model(self):
        """
        Populate the model.
        """
        self.namemodel.clear()
        tags = []
        for tag in self.db.iter_tags():
            tags.append((tag.get_priority(), tag.get_handle(), tag.get_name(),
                         tag.get_color()))

        for row in sorted(tags):
            self.namemodel.add(row)

    def _create_dialog(self):
        """
        Create a dialog box to organize tags.
        """
        # pylint: disable-msg=E1101
        title = _("%(title)s - Gramps") % {'title': _("Organize Tags")}
        top = gtk.Dialog(title)
        top.set_default_size(400, 350)
        top.set_modal(True)
        top.set_transient_for(self.parent_window)
        top.set_has_separator(False)
        top.vbox.set_spacing(5)
        label = gtk.Label('<span size="larger" weight="bold">%s</span>' %
                          _("Organize Tags"))
        label.set_use_markup(True)
        top.vbox.pack_start(label, 0, 0, 5)
        box = gtk.HBox()
        top.vbox.pack_start(box, 1, 1, 5)

        name_titles = [
            ('', NOSORT, 20, INTEGER),  # Priority
            ('', NOSORT, 100),  # Handle
            (_('Name'), NOSORT, 200),
            (_('Color'), NOSORT, 50, COLOR)
        ]
        self.namelist = gtk.TreeView()
        self.namemodel = ListModel(self.namelist, name_titles)

        slist = gtk.ScrolledWindow()
        slist.add_with_viewport(self.namelist)
        slist.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        box.pack_start(slist, 1, 1, 5)
        bbox = gtk.VButtonBox()
        bbox.set_layout(gtk.BUTTONBOX_START)
        bbox.set_spacing(6)
        up = gtk.Button(stock=gtk.STOCK_GO_UP)
        down = gtk.Button(stock=gtk.STOCK_GO_DOWN)
        add = gtk.Button(stock=gtk.STOCK_ADD)
        edit = gtk.Button(stock=gtk.STOCK_EDIT)
        remove = gtk.Button(stock=gtk.STOCK_REMOVE)
        up.connect('clicked', self.cb_up_clicked)
        down.connect('clicked', self.cb_down_clicked)
        add.connect('clicked', self.cb_add_clicked, top)
        edit.connect('clicked', self.cb_edit_clicked, top)
        remove.connect('clicked', self.cb_remove_clicked, top)
        top.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
        top.add_button(gtk.STOCK_HELP, gtk.RESPONSE_HELP)
        bbox.add(up)
        bbox.add(down)
        bbox.add(add)
        bbox.add(edit)
        bbox.add(remove)
        box.pack_start(bbox, 0, 0, 5)
        top.show_all()
        return top

    def cb_up_clicked(self, obj):
        """
        Move the current selection up one row.
        """
        row = self.namemodel.get_selected_row()
        self.namemodel.move_up(row)

    def cb_down_clicked(self, obj):
        """
        Move the current selection down one row.
        """
        row = self.namemodel.get_selected_row()
        self.namemodel.move_down(row)

    def cb_add_clicked(self, button, top):
        """
        Create a new tag.
        """
        tag = Tag()
        tag.set_priority(self.db.get_number_of_tags())
        edit_dialog = EditTag(self.db, top, tag)
        edit_dialog.run()

        if tag.get_handle():
            self.namemodel.add((tag.get_priority(), tag.get_handle(),
                                tag.get_name(), tag.get_color()))

    def cb_edit_clicked(self, button, top):
        """
        Edit the color of an existing tag.
        """
        store, iter_ = self.namemodel.get_selected()
        if iter_ is None:
            return

        tag = self.db.get_tag_from_handle(store.get_value(iter_, 1))
        edit_dialog = EditTag(self.db, top, tag)
        edit_dialog.run()

        store.set_value(iter_, 2, tag.get_name())
        store.set_value(iter_, 3, tag.get_color())

    def cb_remove_clicked(self, button, top):
        """
        Remove the selected tag.
        """
        store, iter_ = self.namemodel.get_selected()
        if iter_ is None:
            return
        tag_handle = store.get_value(iter_, 1)
        tag_name = store.get_value(iter_, 2)

        yes_no = QuestionDialog2(
            _("Remove tag '%s'?") % tag_name,
            _("The tag definition will be removed.  "
              "The tag will be also removed from all objects in the database."
              ), _("Yes"), _("No"))
        prompt = yes_no.run()
        if prompt:

            fnc = {
                'Person':
                (self.db.get_person_from_handle, self.db.commit_person),
                'Family':
                (self.db.get_family_from_handle, self.db.commit_family),
                'Event': (self.db.get_event_from_handle, self.db.commit_event),
                'Place': (self.db.get_place_from_handle, self.db.commit_place),
                'Source':
                (self.db.get_source_from_handle, self.db.commit_source),
                'Repository': (self.db.get_repository_from_handle,
                               self.db.commit_repository),
                'MediaObject':
                (self.db.get_object_from_handle, self.db.commit_media_object),
                'Note': (self.db.get_note_from_handle, self.db.commit_note)
            }

            links = [
                link for link in self.db.find_backlink_handles(tag_handle)
            ]
            # Make the dialog modal so that the user can't start another
            # database transaction while the one removing tags is still running.
            pmon = progressdlg.ProgressMonitor(
                progressdlg.GtkProgressDialog,
                ("", self.parent_window, gtk.DIALOG_MODAL),
                popup_time=2)
            status = progressdlg.LongOpStatus(msg=_("Removing Tags"),
                                              total_steps=len(links),
                                              interval=len(links) // 20)
            pmon.add_op(status)

            msg = _('Delete Tag (%s)') % tag_name
            with DbTxn(msg, self.db) as trans:
                for classname, handle in links:
                    status.heartbeat()
                    obj = fnc[classname][0](handle)  # get from handle
                    obj.remove_tag(tag_handle)
                    fnc[classname][1](obj, trans)  # commit

                self.db.remove_tag(tag_handle, trans)
                self.__change_tag_priority(trans)
            self.namemodel.remove(iter_)
            status.end()
예제 #27
0
class SourceReferences(Gramplet):
    """
    Displays the back references for an object.
    """
    def init(self):
        self.gui.WIDGET = self.build_gui()
        self.gui.get_container_widget().remove(self.gui.textview)
        self.gui.get_container_widget().add_with_viewport(self.gui.WIDGET)
        self.gui.WIDGET.show()

    def build_gui(self):
        """
        Build the GUI interface.
        """
        top = gtk.TreeView()
        titles = [(_('Type'), 0, 100),
                  (_('Name'), 1, 100),
                  ('', 2, 1), #hidden column for the handle
                  ('', 3, 1)] #hidden column for non-localized object type
        self.model = ListModel(top, titles, event_func=self.cb_double_click)
        return top

    def display_backlinks(self, active_handle):
        """
        Display the back references for an object.
        """
        for classname, handle in self.dbstate.db.find_backlink_handles(active_handle):
            for classname, handle in self.dbstate.db.find_backlink_handles(handle):
                name = navigation_label(self.dbstate.db, classname, handle)[0]
                self.model.add((_(classname), name, handle, classname))
            self.set_has_data(self.model.count > 0)

    def get_has_data(self, active_handle):
        """
        Return True if the gramplet has data, else return False.
        """
        if active_handle is None:
            return False
        for classname, handle in self.dbstate.db.find_backlink_handles(active_handle):
            for classname, handle in self.dbstate.db.find_backlink_handles(handle):
                return True
        return False

    def cb_double_click(self, treeview):
        """
        Handle double click on treeview.
        """
        (model, iter_) = treeview.get_selection().get_selected()
        if not iter_:
            return

        (objclass, handle) = (model.get_value(iter_, 3),
                              model.get_value(iter_, 2))

        edit_object(self.dbstate, self.uistate, objclass, handle)

    def db_changed(self):
        self.dbstate.db.connect('source-update', self.update)
        self.connect_signal('Source', self.update)

    def update_has_data(self):
        active_handle = self.get_active('Source')
        self.set_has_data(self.get_has_data(active_handle))

    def main(self):
        active_handle = self.get_active('Source')
        self.model.clear()
        if active_handle:
            self.display_backlinks(active_handle)
        else:
            self.set_has_data(False)
예제 #28
0
 def clearData(self):
     self.m_pModel = ListModel([])
     self.setModel(self.m_pModel)
예제 #29
0
class UpdateAddons(ManagedWindow.ManagedWindow):
    def __init__(self, uistate, track, addon_update_list):
        self.title = _('Available Gramps Updates for Addons')
        ManagedWindow.ManagedWindow.__init__(self, uistate, track,
                                             self.__class__)

        glade = Glade("updateaddons.glade")
        self.update_dialog = glade.toplevel
        self.set_window(self.update_dialog, glade.get_object('title'),
                        self.title)
        self.window.set_size_request(750, 400)

        apply_button = glade.get_object('apply')
        cancel_button = glade.get_object('cancel')
        select_all = glade.get_object('select_all')
        select_all.connect("clicked", self.select_all_clicked)
        select_none = glade.get_object('select_none')
        select_none.connect("clicked", self.select_none_clicked)
        apply_button.connect("clicked", self.install_addons)
        cancel_button.connect("clicked", self.close)

        self.list = ListModel(
            glade.get_object("list"),
            [
                # name, click?, width, toggle
                {
                    "name": _('Select'),
                    "width": 60,
                    "type": TOGGLE,
                    "visible_col": 6,
                    "editable": True
                },  # 0 selected?
                (_('Type'), 1, 180),  # 1 new gramplet
                (_('Name'), 2, 200),  # 2 name (version)
                (_('Description'), 3, 200),  # 3 description
                ('', NOSORT, 0),  # 4 url
                ('', NOSORT, 0),  # 5 id
                {
                    "name": '',
                    "type": TOGGLE
                },  # 6 visible? bool
            ],
            list_mode="tree")
        pos = None
        addon_update_list.sort(key=lambda x: "%s %s" % (x[0], x[2]["t"]))
        last_category = None
        for (status, plugin_url, plugin_dict) in addon_update_list:
            count = get_count(addon_update_list, plugin_dict["t"])
            category = _("%(adjective)s: %(addon)s") % {
                "adjective": status,
                "addon": _(plugin_dict["t"])
            }
            if last_category != category:
                last_category = category
                node = self.list.add([
                    False,  # initially selected?
                    category,
                    "",
                    "",
                    "",
                    "",
                    False
                ])  # checkbox visible?
            iter = self.list.add(
                [
                    False,  # initially selected?
                    "%s %s" % (status, _(plugin_dict["t"])),
                    "%s (%s)" % (plugin_dict["n"], plugin_dict["v"]),
                    plugin_dict["d"],
                    plugin_url,
                    plugin_dict["i"],
                    True
                ],
                node=node)
            if pos is None:
                pos = iter
        if pos:
            self.list.selection.select_iter(pos)
        self.update_dialog.run()

    def build_menu_names(self, obj):
        return (self.title, "")

    def select_all_clicked(self, widget):
        """
        Select all of the addons for download.
        """
        self.list.model.foreach(update_rows, True)
        self.list.tree.expand_all()

    def select_none_clicked(self, widget):
        """
        Select none of the addons for download.
        """
        self.list.model.foreach(update_rows, False)
        self.list.tree.expand_all()

    def install_addons(self, obj):
        """
        Process all of the selected addons.
        """
        self.update_dialog.hide()
        model = self.list.model

        iter = model.get_iter_first()
        length = 0
        while iter:
            iter = model.iter_next(iter)
            if iter:
                length += model.iter_n_children(iter)

        longop = LongOpStatus(
            _("Downloading and installing selected addons..."),
            length,
            1,  # total, increment-by
            can_cancel=True)
        pm = ProgressMonitor(GtkProgressDialog,
                             ("Title", self.window, gtk.DIALOG_MODAL))
        pm.add_op(longop)
        count = 0
        if not config.get('behavior.do-not-show-previously-seen-updates'):
            # reset list
            config.get('behavior.previously-seen-updates')[:] = []

        iter = model.get_iter_first()
        while iter:
            for rowcnt in range(model.iter_n_children(iter)):
                child = model.iter_nth_child(iter, rowcnt)
                row = [model.get_value(child, n) for n in range(6)]
                if longop.should_cancel():
                    break
                elif row[0]:  # toggle on
                    load_addon_file(row[4], callback=LOG.debug)
                    count += 1
                else:  # add to list of previously seen, but not installed
                    if row[5] not in config.get(
                            'behavior.previously-seen-updates'):
                        config.get('behavior.previously-seen-updates').append(
                            row[5])
                longop.heartbeat()
                pm._get_dlg()._process_events()
            iter = model.iter_next(iter)

        if not longop.was_cancelled():
            longop.end()
        if count:
            OkDialog(
                _("Done downloading and installing addons"), "%s %s" %
                (ngettext("%d addon was installed.",
                          "%d addons were installed.", count) % count,
                 _("You need to restart Gramps to see new views.")),
                self.window)
        else:
            OkDialog(_("Done downloading and installing addons"),
                     _("No addons were installed."), self.window)
        self.close()
예제 #30
0
 def __init__(self):
     super(GmailModule, self).__init__()
     self.scopes = ['https://mail.google.com/']
     self.time_elapsed = 0
     self.currentEmailList = ListModel(GmailModule.EmailObject)
     self.threadMessages = ListModel(GmailModule.EmailObject)
예제 #31
0
class ListView(QListView):
    '''
    自定义视图
    '''
    map_listview = []

    # map_listview保存QListView对象和分组名称的对应关系

    def __init__(self):
        '''
        一些初始设置
        '''
        super().__init__()
        self.m_pModel = ListModel()
        self.setModel(self.m_pModel)

    def contextMenuEvent(self, event):
        '''
        上下文菜单
        '''
        hitIndex = self.indexAt(event.pos()).column()
        # 返回鼠标指针相对于接收事件的小部件的位置

        if hitIndex > -1:
            # 找到索引
            pmenu = QMenu(self)
            pDeleteAct = QAction("删除", pmenu)
            pmenu.addAction(pDeleteAct)
            pDeleteAct.triggered.connect(self.deleteItemSlot)
            pSubMenu = QMenu("转移联系人至", pmenu)
            pmenu.addMenu(pSubMenu)
            for item_dic in self.map_listview:
                # 这里我们将每个分组名称取出,新建一个QAction对象,加入到pSubMenu当中。
                pMoveAct = QAction(item_dic['groupname'], pmenu)
                pSubMenu.addAction(pMoveAct)
                pMoveAct.triggered.connect(self.move)
                # 点击这个每个分组的时候就会执行联系人转移分组操作,这里就是move()的调用。
            pmenu.popup(self.mapToGlobal(event.pos()))
            # 显示菜单,以便动作QAction对象在指定的全局位置p处。这里的全局位置p是根据小部件的本地坐标转换为全局坐标的

    def deleteItemSlot(self):
        '''
        删除联系人
        '''
        index = self.currentIndex().row()
        if index > -1:
            self.m_pModel.deleteItem(index)

    def setListMap(self, listview):
        '''
        将分组名称和QListView对象这个字典增加到map_listview数据列表中
        '''
        self.map_listview.append(listview)

    def addItem(self, pitem):
        '''
        新增一个联系人
        '''
        self.m_pModel.addItem(pitem)

    def move(self):
        '''
        实现联系人转移
        '''
        tolistview = self.find(self.sender().text())
        # 点击的分组名称找到对应的QListView对象

        if tolistview is self:
            prelistview = self.sender().text()
            QMessageBox.warning(self, "警告",
                                "该联系人就在{},还怎么移动啊!".format(prelistview))
            # 假设联系人就在将转移的分组,那我们就没有必要转移了
        else:
            index = self.currentIndex().row()
            pItem = self.m_pModel.getItem(index)
            tolistview.addItem(pItem)
            self.m_pModel.deleteItem(index)
            # 否则我们首先要获得这个联系人,然后在将转移的分组中将这个联系人加上,原分组联系人删除

    def find(self, pmenuname):
        '''
        找到分组对象
        '''
        for item_dic in self.map_listview:
            if item_dic['groupname'] == pmenuname:
                return item_dic['listview']