def ShowLogWindow(self, show=True): Logger.Debug(__name__, GT(u'Show log window: {}').format(show)) self.log_window.Show(show) if self.menu_debug.IsChecked(menuid.DEBUG) != show: self.menu_debug.Check(menuid.DEBUG, show)
def OnExportLauncher(self, event=None): Logger.Debug(__name__, u'Export launcher ...') export = GetFileSaveDialog(GetMainWindow(), GT(u'Save Launcher')) if ShowDialog(export): target = export.GetPath() # Create a backup file # FIXME: Create backup files in WriteFile function? overwrite = False if os.path.isfile(target): backup = u'{}.backup'.format(target) shutil.copy(target, backup) overwrite = True try: self.ExportToFile(target) if overwrite: os.remove(backup) except UnicodeEncodeError: detail1 = GT( u'Unfortunately Debreate does not support unicode yet.') detail2 = GT( u'Remove any non-ASCII characters from your project.') ShowErrorDialog(GT(u'Save failed'), u'{}\n{}'.format(detail1, detail2), title=GT(u'Unicode Error')) os.remove(target) # Restore from backup shutil.move(backup, target)
def ProjectOpenLegacy(self, data, filename): Logger.Debug(__name__, GT(u'Legacy project format (text) detected')) def ProjectError(): wx.MessageDialog(self, GT(u'Not a valid Debreate project'), GT(u'Error'), style=wx.OK | wx.ICON_ERROR).ShowModal() if data == wx.EmptyString: ProjectError() return dbrerrno.EBADFT lines = data.split(u'\n') app = lines[0].split(u'-')[0].split(u'[')[1] if app != u'DEBREATE': ProjectError() return dbrerrno.EBADFT # *** Get Control Data *** # control_data = data.split(u'<<CTRL>>\n')[1].split(u'\n<</CTRL>>')[0] depends_data = self.Wizard.GetPage(pgid.CONTROL).Set(control_data) self.Wizard.GetPage(pgid.DEPENDS).Set(depends_data) # *** Get Files Data *** # files_data = data.split(u'<<FILES>>\n')[1].split(u'\n<</FILES>>')[0] self.Wizard.GetPage(pgid.FILES).Set(files_data) # *** Get Scripts Data *** # scripts_data = data.split(u'<<SCRIPTS>>\n')[1].split( u'\n<</SCRIPTS>>')[0] self.Wizard.GetPage(pgid.SCRIPTS).Set(scripts_data) # *** Get Changelog Data *** # clog_data = data.split(u'<<CHANGELOG>>\n')[1].split( u'\n<</CHANGELOG>>')[0] self.Wizard.GetPage(pgid.CHANGELOG).Set(clog_data) # *** Get Copyright Data *** # try: cpright_data = data.split(u'<<COPYRIGHT>>\n')[1].split( u'\n<</COPYRIGHT')[0] self.Wizard.GetPage(pgid.COPYRIGHT).Set(cpright_data) except IndexError: pass # *** Get Menu Data *** # m_data = data.split(u'<<MENU>>\n')[1].split(u'\n<</MENU>>')[0] self.Wizard.GetPage(pgid.LAUNCHERS).Set(m_data) # Get Build Data build_data = data.split(u'<<BUILD>>\n')[1].split(u'\n<</BUILD')[0] self.Wizard.GetPage(pgid.BUILD).Set(build_data) self.ProjectSetDirty(False) # Legacy projects should return None since we can't save in that format return None
def __init__(self, cfgKey=None, cfgSect=None): self.ConfigKey = cfgKey self.ConfigSection = cfgSect if not self.ConfigSection: self.ConfigSection = u'GENERAL' if self.ConfigKey == None: self.ConfigKey = self.GetName() # Add to recognized configuration keys SetDefaultConfigKey(self.ConfigKey, self.GetDefaultValue()) # Set state using config file if found state = ReadConfig(self.ConfigKey) ret_codes = ( ConfCode.FILE_NOT_FOUND, ConfCode.KEY_NOT_DEFINED, ConfCode.KEY_NO_EXIST, ) # FIXME: if state not in (ret_codes): self.SetValue(state) else: Logger.Debug(__name__, u'Key not found: {}'.format(self.ConfigKey)) # *** Event Handling *** # if isinstance(self, wx.CheckBox): self.Bind(wx.EVT_CHECKBOX, self.OnToggle)
def OnProjectNew(self, event=None): Logger.Debug( __name__, GT(u'Project loaded before OnProjectNew: {}').format( self.ProjectIsLoaded())) return self.ProjectClose()
def ShowMessageDialog(text, title=GT(u'Message'), details=None, module=None, parent=None, linewrap=0): if not parent: parent = GetMainWindow() logger_text = text if isinstance(text, (tuple, list)): logger_text = u'; '.join(text) text = u'\n'.join(text) if details: logger_text = u'{}:\n{}'.format(logger_text, details) message_dialog = DetailedMessageDialog(parent, title, ICON_INFORMATION, text, linewrap=linewrap) if details: message_dialog.SetDetails(details) Logger.Debug(module, logger_text) message_dialog.ShowModal()
def OnAccept(self, event=None): if self.IsSaveDialog(): if self.Extension: if not self.Filename.endswith(self.Extension): # Adds extensions if not specified self.SetFilename(self.Filename) if self.Path: if os.path.isfile(self.Path): overwrite = OverwriteDialog(self, self.Path) if not ShowDialog(overwrite): return try: os.remove(self.Path) except OSError: # File was removed before confirmation Logger.Debug( __name__, u'Item was removed before confirmation: {}'.format( self.Path)) # Because we are not using default FileDialog methods, we must set # directory manually. self.SetDirectory(os.path.dirname(self.Path)) # File & directory dialogs should call this function ChangeWorkingDirectory(self.GetDirectory()) self.EndModal(self.AffirmativeId)
def InitPage(self): Logger.Debug( __name__, GT(u'Page {} does not override inherited method InitPage').format( self.GetName())) return False
def SetCompression(self, compression_id): for Z in self.menu_compress.GetMenuItems(): Z_ID = Z.GetId() if compression_id == Z_ID: Z.Check() Logger.Debug( __name__, GT(u'Project compression set to "{}"'.format( compression_formats[Z_ID]))) return Logger.Debug( __name__, GT(u'Urecognized compression ID: {}'.format(compression_id)))
def OnAccept(self, event=None): path = self.GetPath() if os.path.isdir(path): self.EndModal(wx.ID_OK) return Logger.Debug(__name__, u'Path is not a directory: {}'.format(path))
def OnToggleLogWindow(self, event=None): Logger.Debug(__name__, GT(u'Toggling log window')) if event != None: self.ShowLogWindow(self.menu_debug.IsChecked(menuid.DEBUG)) return self.menu_debug.Check(menuid.DEBUG, self.log_window.IsShown())
def _copy(f_src, f_tgt, exe=False): # NOTE: Python 3 appears to have follow_symlinks option for shutil.copy # FIXME: copying nested symbolic link may not work if os.path.isdir(f_src): if os.path.islink(f_src) and no_follow_link: Logger.Debug( __name__, u'Adding directory symbolic link to stage: {}'. format(f_tgt)) os.symlink(os.readlink(f_src), f_tgt) else: Logger.Debug( __name__, u'Adding directory to stage: {}'.format(f_tgt)) shutil.copytree(f_src, f_tgt) os.chmod(f_tgt, 0o0755) elif os.path.isfile(f_src): if os.path.islink(f_src) and no_follow_link: Logger.Debug( __name__, u'Adding file symbolic link to stage: {}'. format(f_tgt)) os.symlink(os.readlink(f_src), f_tgt) else: if exe: Logger.Debug( __name__, u'Adding executable to stage: {}'.format( f_tgt)) else: Logger.Debug( __name__, u'Adding file to stage: {}'.format(f_tgt)) shutil.copy(f_src, f_tgt) # Set FILE permissions if exe: os.chmod(f_tgt, 0o0755) else: os.chmod(f_tgt, 0o0644)
def GetCompressionId(z_value): for z_id in compression_formats: if z_value == compression_formats[z_id]: return z_id Logger.Debug(__name__, GT(u'Compression ID not found for "{}" value'.format(z_value))) return None
def OnTimerStop(self, event=None): Logger.Debug(__name__, u'Destroying TimedProgressDialog instance') if wx.MAJOR_VERSION <= 2: # Dialog needs to be closed before destroying for wx 2.8 self.Close() self.Destroy()
def OnWizardBtnPage(self, event=None): #@UnusedVariable ID = self.Wizard.GetCurrentPageId() Logger.Debug(__name__, GT(u'Event: EVT_CHANGE_PAGE, Page ID: {}').format(ID)) menu_page = self.GetMenu(menuid.PAGE) if not menu_page.IsChecked(ID): menu_page.Check(ID, True)
def UpdateCache(self, args=None): Logger.Debug(__name__, GT(u'Updating cache ...')) UpdateDistNamesCache(self.chk_unstable.GetValue(), self.chk_obsolete.GetValue(), self.chk_generic.GetValue()) self.timer.Stop()
def ImportFromFile(self, d_type, d_string): Logger.Debug(__name__, GT(u'Importing {}: {}'.format(d_type, d_string))) values = d_string.split(u', ') for V in values: self.lst_deps.InsertStringItem(0, d_type) self.lst_deps.SetStringItem(0, 1, V)
def InitMountItems(self): # Failsafe conditional in case of errors reading user home directory home_exists = os.path.isdir(PATH_home) if home_exists: home_item = self.AppendItem( self.root_item, GT(u'Home directory'), PATH_home, ImageList.GetImageIndex(u'folder-home'), expImage=ImageList.GetImageIndex(u'folder-home-open')) self.mount_list.append(home_item) # List storage devices currently mounted on system stdevs = GetMountedStorageDevices() for DEV in stdevs: # Do not re-add home directory in case it is mounted on its own partition if DEV.MountPoint == PATH_home: continue add_item = os.path.ismount(DEV.MountPoint) if add_item: for PITEM in self.mount_list: if DEV.MountPoint == PITEM.Path: add_item = False break if add_item: Logger.Debug( __name__, u'Adding new mount PathItem instance: {}'.format( DEV.Label)) self.mount_list.append( self.AppendItem(self.root_item, DEV.Label, DEV.MountPoint, ImageList.GetImageIndex(DEV.Type))) continue else: Logger.Debug( __name__, u'PathItem instance for "{}" directory already exists'. format(DEV.MountPoint))
def ProjectOpenArchive(self, filename, file_type): Logger.Debug(__name__, GT(u'Compressed project archive detected')) if file_type not in compression_mimetypes: Logger.Error( __name__, GT(u'Cannot open project with compression mime type "{}"'. format(file_type))) return dbrerrno.EBADFT compression_id = compression_mimetypes[file_type] z_format = compression_formats[compression_id] if z_format in (u'tar', u'zip'): z_format = u'r' else: z_format = u'r:{}'.format(z_format) Logger.Debug( __name__, GT(u'Opening compressed project with "{}" format').format( z_format)) stage = CreateStage() p_archive = CompressionHandler(compression_id) ret_code = p_archive.Uncompress(filename, stage) if isinstance(ret_code, tuple) and ret_code[0]: ShowErrorDialog(u'{}: {}'.format(GT(u'Project load error'), ret_code[1]), ret_code[0], parent=self) return dbrerrno.EBADFT self.Wizard.ImportPagesInfo(stage) RemoveStage(stage) # Mark project as loaded return dbrerrno.SUCCESS
def OnUpdateProgress(self, event=None): if event: if isinstance(event, wx.TimerEvent): if not self.timer.IsRunning(): Logger.Debug(__name__, GT(u'Timer stopped. Stopping gauge ...')) return self.gauge.Pulse()
def Destroy(self, *args, **kwargs): # Re-enable parent/main window if previously disabled # ???: May not be necessary main_window = GetMainWindow() if not FieldEnabled(main_window): Logger.Debug(__name__, u'Re-enabling main window') main_window.Enable() if self.Parent and not FieldEnabled(self.Parent): Logger.Debug(__name__, u'Re-enabling parent') self.Parent.Enable() if wx.MAJOR_VERSION < 3: self.EndModal(0) return wx.ProgressDialog.Destroy(self, *args, **kwargs)
def OnSetCompression(self, event=None): if event: event_id = event.GetId() Logger.Debug( __name__, GT(u'OnSetCompression; Event ID: {}').format(event_id)) Logger.Debug( __name__, GT(u'OnSetCompression; Compression from event ID: {}').format( compression_formats[event_id])) if event_id in compression_formats: WriteConfig(u'compression', compression_formats[event_id]) return Logger.Warn( __name__, GT(u'OnSetCompression; Could not write to config, ID not found in compression formats: {}' ).format(event_id))
def OnBuildMD5Sum(self, stage): Logger.Debug(__name__, GT(u'Creating MD5sum file in {}').format(stage)) WriteMD5(stage) return GT(u'md5sums file created: {}'.format( os.path.isfile(ConcatPaths(( stage, u'DEBIAN/md5sums', )))))
def OnEndLabelEdit(self, event=None): if event: if event.IsEditCancelled(): Logger.Debug(__name__, u'Vetoing due to cancelled edit') event.Veto() return item = event.GetItem() for I in self.item_list: if I.GetBaseItem() == item: item = I break new_label = event.GetLabel() item_dir = os.path.dirname(item.Path) new_path = ConcatPaths((item_dir, new_label)) try: if os.path.exists(new_path): msg_l1 = GT(u'Name already exists:') ShowErrorDialog(u'{}\n\n{}'.format(msg_l1, new_path)) event.Veto() return os.rename(item.Path, new_path) ## ???: Another way to test if rename was successful? if os.path.exists(new_path): # Items path must be updated I.Path = new_path except OSError: Logger.Debug( __name__, u'Item not renamed, traceback details below:\n\n{}'.format( traceback.format_exc())) event.Veto() Logger.Debug(__name__, u'New item path: {}'.format(item.Path))
def CenterOnPrimaryDisplay(window): Logger.Debug( __name__, u'Attempting to center window: {} ({})'.format(window.Name, window)) display_rect = GetPrimaryDisplayRect() Logger.Debug(__name__, u'Primary display: {}'.format(display_rect)) if not display_rect: return False window_size = window.GetSizeTuple() dx = display_rect[2] dy = display_rect[3] dw = display_rect[0] dh = display_rect[1] x_diff = (dw - window_size[0]) / 2 y_diff = (dh - window_size[1]) / 2 debug = DebugEnabled() if debug: print(u' X difference: {}'.format(x_diff)) print(u' Y difference: {}'.format(y_diff)) # NOTE: May be a few pixels off pos_x = dx + x_diff pos_y = dy + y_diff if debug: print(u'\n Theoretical position: {}'.format(( pos_x, pos_y, ))) print(u' Actual Position: {}'.format(window.GetPositionTuple())) window.SetPosition((pos_x, pos_y)) return True
def SetSectionLabel(self, section=None): if section == None: section = self.sel_section.GetStringSelection() if section in sections: Logger.Debug(__name__, u'Setting section to {}'.format(section)) self.LabelSection.SetLabel(sections[section]) return True return False
def OnBuildCheckPackage(self, targetPackage): Logger.Debug( __name__, GT(u'Checking package "{}" for lintian errors ...').format( os.path.basename(targetPackage))) # FIXME: commands module deprecated? output = commands.getoutput(u'{} "{}"'.format( GetExecutable(u'lintian'), targetPackage)) return output
def SendToTrash(self, item_list): path_list = [] for I in item_list: if not os.access(I.Path, os.W_OK): ShowErrorDialog( GT(u'Cannot move "{}" to trash, no write access').format( I.Path), warn=True) return False path_list.append(I.Path) msg_l1 = GT(u'Move the following items to trash?') msg_l2 = u'\n'.join(path_list) if ConfirmationDialog(GetMainWindow(), GT(u'Delete'), u'{}\n\n{}'.format(msg_l1, msg_l2)).Confirmed(): arg_list = list(path_list) # Use 'force' argument to avoid crash on non-existing paths arg_list.insert(0, u'-f') ExecuteCommand(GetExecutable(u'gvfs-trash'), arg_list) Logger.Debug(__name__, u'Paths deleted') self.DeleteItems(item_list) Logger.Debug(__name__, u'Items deleted') # Confirm that paths were removed for P in path_list: if os.path.exists(P): Logger.Debug(__name__, u'Failed to remove "{}"'.format(P)) return False Logger.Debug(__name__, u'Items successfully moved to trash') return True return False
def __init__(self, item, path, label=None): if path == None: # So that calls to os.path.exists(PathItem.Path) do not raise exception path = wx.EmptyString self.Item = item self.Path = path self.Label = label self.Children = [] self.Type = None if self.Path: self.Type = GetFileMimeType(self.Path) executables_binary = (u'x-executable', ) executables_text = ( u'x-python', u'x-shellscript', ) # Don't use MIME type 'inode' for directories (symlinks are inodes) if os.path.isdir(self.Path): self.Type = u'folder' elif self.Type.startswith(u'image'): self.Type = u'image' elif self.Type.startswith(u'audio'): self.Type = u'audio' elif self.Type.startswith(u'video'): self.Type = u'video' else: # Exctract second part of MIME type self.Type = self.Type.split(u'/')[-1] if self.Type in executables_binary: self.Type = u'executable-binary' elif self.Type in executables_text: self.Type = u'executable-script' self.ImageIndex = ImageList.GetImageIndex(self.Type) # Use generic 'file' image as default if self.ImageIndex == ImageList.GetImageIndex(u'failsafe'): self.ImageIndex = ImageList.GetImageIndex(u'file') Logger.Debug( __name__, u'PathItem type: {} ({})'.format(self.Type, self.Path))
def ImportFromFile(self, filename): Logger.Debug(__name__, GT(u'Importing page info from {}').format(filename)) if not os.path.isfile(filename): return dbrerrno.ENOENT files_data = ReadFile(filename, split=True) # Lines beginning with these characters will be ignored ignore_characters = ( u'', u' ', u'#', ) target = None targets_list = [] for L in files_data: if not TextIsEmpty(L) and L[0] not in ignore_characters: if u'[' in L and u']' in L: target = L.split(u'[')[-1].split(u']')[0] continue if target: executable = (len(L) > 1 and L[-2:] == u' *') if executable: L = L[:-2] targets_list.append((target, L, executable)) missing_files = [] for T in targets_list: # FIXME: Create method in FileList class to retrieve all missing files if not os.path.exists(T[1]): missing_files.append(T[1]) source_file = os.path.basename(T[1]) source_dir = os.path.dirname(T[1]) self.lst_files.AddFile(source_file, source_dir, T[0], executable=T[2]) if len(missing_files): main_window = GetMainWindow() err_line1 = GT(u'The following files/folders are missing from the filesystem.') err_line2 = GT(u'They will be highlighted on the Files page.') DetailedMessageDialog(main_window, title=GT(u'Warning'), icon=ICON_ERROR, text=u'\n'.join((err_line1, err_line2)), details=u'\n'.join(missing_files)).ShowModal() return 0