def startCollab(self, view):
     """
     Send the provided C{sublime.View} contents to the connected peer.
     """
     self.view = view
     self.view.set_read_only(True)
     viewName = self.view.file_name()
     if not viewName == None:
         viewName = os.path.basename(viewName)
     else:
         viewName = 'NONAME'
     totalToSend = self.view.size()
     begin = 0
     end = MAX_CHUNK_SIZE
     # now we make sure we are connected... better way to do this?
     while not self.state == interface.STATE_CONNECTED:
         time.sleep(1.0)
         if (self.state == interface.STATE_DISCONNECTING) or (self.state == interface.STATE_DISCONNECTED):
             logger.error('While waiting to share view over a connection the peer was disconnected!')
             self.disconnect()
             return
     logger.info('Sharing view %s with %s' % (self.view.file_name(), self.sharingWithUser))
     self.toAck = []
     self.sendMessage(interface.SHARE_VIEW, payload=('%s|%s' % (viewName, totalToSend)))
     while begin < totalToSend:
         chunkToSend = self.view.substr(sublime.Region(begin, end))
         self.toAck.append(len(chunkToSend))
         self.sendMessage(interface.VIEW_CHUNK, payload=chunkToSend)
         begin = begin + MAX_CHUNK_SIZE
         end = end + MAX_CHUNK_SIZE
         status_bar.progress_message("sending view to %s" % self.sharingWithUser, begin, totalToSend)
     self.sendMessage(interface.END_OF_VIEW, payload=view.settings().get('syntax'))
     self.view.set_read_only(False)
     # start the view monitoring thread
     self.viewMonitorThread.start()
 def startCollab(self, view):
     """
     Send the provided C{sublime.View} contents to the connected peer.
     """
     self.view = view
     self.view.set_read_only(True)
     viewName = self.view.file_name()
     if not viewName == None:
         viewName = os.path.basename(viewName)
     else:
         viewName = 'NONAME'
     totalToSend = self.view.size()
     begin = 0
     end = MAX_CHUNK_SIZE
     # now we make sure we are connected... better way to do this?
     while not self.state == base.STATE_CONNECTED:
         time.sleep(1.0)
         if (self.state == base.STATE_DISCONNECTING) or (self.state == base.STATE_DISCONNECTED):
             self.logger.error('While waiting to share view over a connection the peer was disconnected!')
             self.disconnect()
             return
     self.logger.info('Sharing view %s with %s' % (self.view.file_name(), self.sharingWithUser))
     self.toAck = []
     self.sendMessage(base.SHARE_VIEW, payload=('%s|%s' % (viewName, totalToSend)))
     while begin < totalToSend:
         chunkToSend = self.view.substr(sublime.Region(begin, end))
         self.toAck.append(len(chunkToSend))
         self.sendMessage(base.VIEW_CHUNK, payload=chunkToSend)
         begin = begin + MAX_CHUNK_SIZE
         end = end + MAX_CHUNK_SIZE
         status_bar.progress_message("sending view to %s" % self.sharingWithUser, begin, totalToSend)
     self.sendMessage(base.END_OF_VIEW, payload=view.settings().get('syntax'))
     self.view.set_read_only(False)
     # start the view monitoring thread
     self.viewMonitorThread.start()
Exemple #3
0
 def resyncCollab(self):
     """
     Resync the shared editor contents between the host and the partner.
     """
     status_bar.status_message('RESYNCING VIEW CONTENT WITH PEER')
     self.view.set_read_only(True)
     totalToSend = self.view.size()
     begin = 0
     end = MAX_CHUNK_SIZE
     # now we make sure we are connected... better way to do this?
     while not self.state == interface.STATE_CONNECTED:
         time.sleep(1.0)
         if (self.state == interface.STATE_DISCONNECTING) or (
                 self.state == interface.STATE_DISCONNECTED):
             logger.error(
                 'While waiting to resync view over a connection the peer was disconnected!'
             )
             self.disconnect()
             return
     view_name = self.view.file_name()
     if not view_name:
         view_name = self.view.name()
     logger.info('Resyncing view %s with %s' %
                 (view_name, self.sharingWithUser))
     self.toAck = []
     self.sendMessage(interface.RESHARE_VIEW, payload=str(totalToSend))
     while begin < totalToSend:
         chunkToSend = self.view.substr(sublime.Region(begin, end))
         self.toAck.append(len(chunkToSend))
         self.sendMessage(interface.VIEW_CHUNK, payload=chunkToSend)
         begin = begin + MAX_CHUNK_SIZE
         end = end + MAX_CHUNK_SIZE
         status_bar.progress_message(
             "sending view to %s" % self.sharingWithUser, begin,
             totalToSend)
     self.sendMessage(interface.END_OF_VIEW,
                      payload=self.view.settings().get('syntax'))
     self.view.set_read_only(False)
     # send view position as it stands now so the partner view is positioned appropriately post-resync
     viewRegionLines = self.view.split_by_newlines(
         self.view.visible_region())
     lineIdx = len(viewRegionLines) / 2 - 1
     if lineIdx < 0:
         lineIdx = 0
     viewCenterRegion = viewRegionLines[lineIdx]
     self.sendViewPositionUpdate(viewCenterRegion)
     # start the view monitoring thread if not already running
     if not self.viewMonitorThread.is_alive():
         self.viewMonitorThread.start()
 def resyncCollab(self):
     """
     Resync the shared editor contents between the host and the partner.
     """
     status_bar.status_message('RESYNCING VIEW CONTENT WITH PEER')
     self.view.set_read_only(True)
     totalToSend = self.view.size()
     begin = 0
     end = MAX_CHUNK_SIZE
     # now we make sure we are connected... better way to do this?
     while not self.state == interface.STATE_CONNECTED:
         time.sleep(1.0)
         if (self.state == interface.STATE_DISCONNECTING) or (self.state == interface.STATE_DISCONNECTED):
             logger.error('While waiting to resync view over a connection the peer was disconnected!')
             self.disconnect()
             return
     view_name = self.view.file_name()
     if not view_name:
         view_name = self.view.name()
     logger.info('Resyncing view %s with %s' % (view_name, self.sharingWithUser))
     self.toAck = []
     self.sendMessage(interface.RESHARE_VIEW, payload=str(totalToSend))
     while begin < totalToSend:
         chunkToSend = self.view.substr(sublime.Region(begin, end))
         self.toAck.append(len(chunkToSend))
         self.sendMessage(interface.VIEW_CHUNK, payload=chunkToSend)
         begin = begin + MAX_CHUNK_SIZE
         end = end + MAX_CHUNK_SIZE
         status_bar.progress_message("sending view to %s" % self.sharingWithUser, begin, totalToSend)
     self.sendMessage(interface.END_OF_VIEW, payload=self.view.settings().get('syntax'))
     self.view.set_read_only(False)
     # send view position as it stands now so the partner view is positioned appropriately post-resync
     viewRegionLines = self.view.split_by_newlines(self.view.visible_region())
     lineIdx = len(viewRegionLines) / 2 - 1
     if lineIdx < 0:
         lineIdx = 0
     viewCenterRegion = viewRegionLines[lineIdx]
     self.sendViewPositionUpdate(viewCenterRegion)
     # start the view monitoring thread if not already running
     if not self.viewMonitorThread.is_alive():
         self.viewMonitorThread.start()
 def handleViewChanges(self):
     """
     Runs on the main UI event loop.
     Goes through the list of events queued up to modify the shared view
     and applies them to the associated view.
     """
     self.toDoToViewQueueLock.acquire()
     while len(self.toDoToViewQueue) > 0:
         toDo = self.toDoToViewQueue.pop(0)
         if len(toDo) == 2:
             logger.debug('Handling view change %s with size %d payload' % (interface.numeric_to_symbolic[toDo[0]], len(toDo[1])))
             if (toDo[0] == interface.SHARE_VIEW) or (toDo[0] == interface.RESHARE_VIEW):
                 self.totalNewViewSize = 0
                 if toDo[0] == interface.SHARE_VIEW:
                     self.view = sublime.active_window().new_file()
                     payloadBits = toDo[1].split('|')
                     if payloadBits[0] == 'NONAME':
                         self.view.set_name('SHARING-WITH-%s' % self.sharingWithUser)
                     else:
                         self.view.set_name(payloadBits[0])
                     self.totalNewViewSize = int(payloadBits[1])
                 else:
                     # resync event, purge the old view in preparation for the fresh content
                     logger.debug('resyncing view')
                     self.lastResyncdPosition = 0
                     self.totalNewViewSize = int(toDo[1])
                 self.view.set_read_only(True)
                 self.view.set_scratch(True)
                 status_bar.progress_message("receiving view from %s" % self.sharingWithUser, self.view.size(), self.totalNewViewSize)
             elif toDo[0] == interface.VIEW_CHUNK:
                 self.view.set_read_only(False)
                 self.viewPopulateEdit = self.view.begin_edit()
                 # if we are a resync chunk...
                 if hasattr(self, 'lastResyncdPosition'):
                     self.view.replace(self.viewPopulateEdit,  \
                         sublime.Region(self.lastResyncdPosition, self.lastResyncdPosition + len(toDo[1])), \
                         toDo[1])
                     self.lastResyncdPosition += len(toDo[1])
                 else:
                     self.view.insert(self.viewPopulateEdit, self.view.size(), toDo[1])
                 self.view.end_edit(self.viewPopulateEdit)
                 self.viewPopulateEdit = None
                 self.view.set_read_only(True)
                 status_bar.progress_message("receiving view from %s" % self.sharingWithUser, self.view.size(), self.totalNewViewSize)
             elif toDo[0] == interface.END_OF_VIEW:
                 self.view.set_syntax_file(toDo[1])
                 if hasattr(self, 'lastResyncdPosition'):
                     del self.lastResyncdPosition
                 status_bar.progress_message("receiving view from %s" % self.sharingWithUser, self.view.size(), self.totalNewViewSize)
                 # view is populated and configured, lets share!
                 self.onStartCollab()
             elif toDo[0] == interface.SELECTION:
                 status_bar.heartbeat_message('sharing with %s' % self.str())
                 regions = []
                 for regionMatch in REGION_PATTERN.finditer(toDo[1]):
                     regions.append(sublime.Region(int(regionMatch.group(1)), int(regionMatch.group(2))))
                 self.recvSelectionUpdate(regions)
             elif toDo[0] == interface.POSITION:
                 status_bar.heartbeat_message('sharing with %s' % self.str())
                 regionMatch = REGION_PATTERN.search(toDo[1])
                 if regionMatch:
                     self.recvViewPositionUpdate(sublime.Region(int(regionMatch.group(1)), int(regionMatch.group(2))))
         elif len(toDo) == 3:
             status_bar.heartbeat_message('sharing with %s' % self.str())
             # edit event
             assert toDo[0] == interface.EDIT
             # make the shared selection the ACTUAL selection
             self.view.sel().clear()
             for region in self.view.get_regions(self.sharingWithUser):
                 self.view.sel().add(region)
             self.view.erase_regions(self.sharingWithUser)
             self.recvEdit(toDo[1], toDo[2])
     self.toDoToViewQueueLock.release()
Exemple #6
0
 def handleViewChanges(self):
     """
     Runs on the main UI event loop.
     Goes through the list of events queued up to modify the shared view
     and applies them to the associated view.
     """
     self.toDoToViewQueueLock.acquire()
     while len(self.toDoToViewQueue) > 0:
         toDo = self.toDoToViewQueue.pop(0)
         if len(toDo) == 2:
             logger.debug(
                 'Handling view change %s with size %d payload' %
                 (interface.numeric_to_symbolic[toDo[0]], len(toDo[1])))
             if (toDo[0] == interface.SHARE_VIEW) or (
                     toDo[0] == interface.RESHARE_VIEW):
                 self.totalNewViewSize = 0
                 if toDo[0] == interface.SHARE_VIEW:
                     self.view = sublime.active_window().new_file()
                     payloadBits = toDo[1].split('|')
                     if payloadBits[0] == 'NONAME':
                         self.view.set_name('SHARING-WITH-%s' %
                                            self.sharingWithUser)
                     else:
                         self.view.set_name(payloadBits[0])
                     self.totalNewViewSize = int(payloadBits[1])
                 else:
                     # resync event, purge the old view in preparation for the fresh content
                     logger.debug('resyncing view')
                     self.lastResyncdPosition = 0
                     self.totalNewViewSize = int(toDo[1])
                 self.view.set_read_only(True)
                 self.view.set_scratch(True)
                 status_bar.progress_message(
                     "receiving view from %s" % self.sharingWithUser,
                     self.view.size(), self.totalNewViewSize)
             elif toDo[0] == interface.VIEW_CHUNK:
                 self.view.set_read_only(False)
                 self.viewPopulateEdit = self.view.begin_edit()
                 # if we are a resync chunk...
                 if hasattr(self, 'lastResyncdPosition'):
                     self.view.replace(self.viewPopulateEdit,  \
                         sublime.Region(self.lastResyncdPosition, self.lastResyncdPosition + len(toDo[1])), \
                         toDo[1])
                     self.lastResyncdPosition += len(toDo[1])
                 else:
                     self.view.insert(self.viewPopulateEdit,
                                      self.view.size(), toDo[1])
                 self.view.end_edit(self.viewPopulateEdit)
                 self.viewPopulateEdit = None
                 self.view.set_read_only(True)
                 status_bar.progress_message(
                     "receiving view from %s" % self.sharingWithUser,
                     self.view.size(), self.totalNewViewSize)
             elif toDo[0] == interface.END_OF_VIEW:
                 self.view.set_syntax_file(toDo[1])
                 if hasattr(self, 'lastResyncdPosition'):
                     del self.lastResyncdPosition
                 status_bar.progress_message(
                     "receiving view from %s" % self.sharingWithUser,
                     self.view.size(), self.totalNewViewSize)
                 # view is populated and configured, lets share!
                 self.onStartCollab()
             elif toDo[0] == interface.SELECTION:
                 status_bar.heartbeat_message('sharing with %s' %
                                              self.str())
                 regions = []
                 for regionMatch in REGION_PATTERN.finditer(toDo[1]):
                     regions.append(
                         sublime.Region(int(regionMatch.group(1)),
                                        int(regionMatch.group(2))))
                 self.recvSelectionUpdate(regions)
             elif toDo[0] == interface.POSITION:
                 status_bar.heartbeat_message('sharing with %s' %
                                              self.str())
                 regionMatch = REGION_PATTERN.search(toDo[1])
                 if regionMatch:
                     self.recvViewPositionUpdate(
                         sublime.Region(int(regionMatch.group(1)),
                                        int(regionMatch.group(2))))
         elif len(toDo) == 3:
             status_bar.heartbeat_message('sharing with %s' % self.str())
             # edit event
             assert toDo[0] == interface.EDIT
             # make the shared selection the ACTUAL selection
             self.view.sel().clear()
             for region in self.view.get_regions(self.sharingWithUser):
                 self.view.sel().add(region)
             self.view.erase_regions(self.sharingWithUser)
             self.recvEdit(toDo[1], toDo[2])
     self.toDoToViewQueueLock.release()