def __init__(self, parent=None): super(FileBrowserDock, self).__init__(parent) self.initDock("File Browser") # make sure icons are loaded Icons.load() # self.openFunction = openFunc # tree view self.fileTree = widgets.FileSystemTreeView() self.fileTree.set_root_path(os.getcwd()) self.contextMenu = FileBrowserMenu() self.fileTree.set_context_menu(self.contextMenu) # enable drag and drop self.fileTree.setDragEnabled(True) self.fileTree.setDragDropMode( QtWidgets.QAbstractItemView.DragDrop) self.fileTree.viewport().setAcceptDrops(True) self.fileTree.setDropIndicatorShown(True) # To Do -- not use a private member -- self.fileTree._fs_model_source.setReadOnly(False) self.fileTree.setEditTriggers( QtWidgets.QAbstractItemView.NoEditTriggers) self.fileTree.setDefaultDropAction(QtCore.Qt.MoveAction) # Folder button self.menuHLayout = QtWidgets.QHBoxLayout() self.menuHLayout.setContentsMargins(1, 1, 1, 1) self.menuHLayout.addStretch(1) self.menuBtn = QtWidgets.QPushButton(Icons.folder, "...", self) self.menuBtn.setFlat(True) self.menuBtn.setStyleSheet("background-color: " "rgba(255, 255, 255, 0);") self.menuHLayout.addWidget(self.menuBtn) self.menuVLayout = QtWidgets.QVBoxLayout() self.menuVLayout.setContentsMargins(1, 1, 1, 1) self.menuVLayout.addLayout(self.menuHLayout) self.menuVLayout.addStretch(1) self.fileTree.setLayout(self.menuVLayout) self.dirContextMenu = DirMenu() self.menuBtn.setMenu(self.dirContextMenu) self.dirContextMenu.parentDirAction.triggered.connect( self.onParentDirClicked) self.dirContextMenu.openDirAction.triggered.connect( self.onOpenDirClicked) # add everything to the dock self.contents = QtWidgets.QWidget() self.layout = QtWidgets.QGridLayout(self.contents) self.layout.addWidget(self.fileTree, 0, 0, 1, 1) self.setWidget(self.contents) self.fileTree.doubleClicked.connect(self.onOpenItem) self.contextMenu.OpenAction.triggered.connect(self.openFile)
def __init__(self, parent=None): super(FileBrowserDock, self).__init__(parent) self.initDock("File Browser") # make sure icons are loaded Icons.load() # self.openFunction = openFunc # tree view self.fileTree = widgets.FileSystemTreeView() self.fileTree.set_root_path(os.getcwd()) self.contextMenu = FileBrowserMenu() self.fileTree.set_context_menu(self.contextMenu) # enable drag and drop self.fileTree.setDragEnabled(True) self.fileTree.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop) self.fileTree.viewport().setAcceptDrops(True) self.fileTree.setDropIndicatorShown(True) # To Do -- not use a private member -- self.fileTree._fs_model_source.setReadOnly(False) self.fileTree.setEditTriggers( QtWidgets.QAbstractItemView.NoEditTriggers) self.fileTree.setDefaultDropAction(QtCore.Qt.MoveAction) # Folder button self.menuHLayout = QtWidgets.QHBoxLayout() self.menuHLayout.setContentsMargins(1, 1, 1, 1) self.menuHLayout.addStretch(1) self.menuBtn = QtWidgets.QPushButton(Icons.folder, "...", self) self.menuBtn.setFlat(True) self.menuBtn.setStyleSheet("background-color: " "rgba(255, 255, 255, 0);") self.menuHLayout.addWidget(self.menuBtn) self.menuVLayout = QtWidgets.QVBoxLayout() self.menuVLayout.setContentsMargins(1, 1, 1, 1) self.menuVLayout.addLayout(self.menuHLayout) self.menuVLayout.addStretch(1) self.fileTree.setLayout(self.menuVLayout) self.dirContextMenu = DirMenu() self.menuBtn.setMenu(self.dirContextMenu) self.dirContextMenu.parentDirAction.triggered.connect( self.onParentDirClicked) self.dirContextMenu.openDirAction.triggered.connect( self.onOpenDirClicked) # add everything to the dock self.contents = QtWidgets.QWidget() self.layout = QtWidgets.QGridLayout(self.contents) self.layout.addWidget(self.fileTree, 0, 0, 1, 1) self.setWidget(self.contents) self.fileTree.doubleClicked.connect(self.onOpenItem) self.contextMenu.OpenAction.triggered.connect(self.openFile)
def display(self, desc, event): uri = desc.get_uri() if not gnomevfs.exists(uri): return file_info = gnomevfs.get_file_info(uri) is_dir = files.is_dir(file_info) icon_manager = Icons(self) if is_dir: pixbuf = icon_manager.retrieve_icon(u'stock_folder', gtk.STOCK_DIRECTORY) self.__appendMenuItem(label=menu0001, pixbuf=pixbuf, callback=lambda a: self.__set_repository(uri)) pixbuf = None else: self.__appendMenuItem(stock=gtk.STOCK_OPEN, callback=lambda a: self.__open_file(uri)) if is_dir: self.__appendSeperator() pixbuf = icon_manager.retrieve_icon(gtk.STOCK_NEW, gtk.STOCK_NEW) self.__appendMenuItem(label=menu0003, pixbuf=pixbuf, callback=lambda a: self.__create_file_in(uri)) self.__appendMenuItem(label=menu0010, pixbuf=pixbuf, callback=lambda a: self.__create_folder_in(uri)) self.__appendSeperator() pixbuf = None if gnomevfs.exists(uri) and uri.is_local: pixbuf = None if icon_manager.theme.has_icon(u'gnome-terminal'): pixbuf = icon_manager.theme.load_icon(u'gnome-terminal', 16, gtk.ICON_LOOKUP_USE_BUILTIN) self.__appendMenuItem(label=menu0011, pixbuf=pixbuf, callback=lambda a: self.__open_terminal(uri)) pixbuf = icon_manager.retrieve_icon(u'stock_open', gtk.STOCK_OPEN) self.__appendMenuItem(label=u'Browse...', pixbuf=pixbuf, callback=lambda a: self.__open_file_browser(uri)) self.__appendSeperator() self.__appendMenuItem(stock=gtk.STOCK_CUT, sensitive=False) self.__appendMenuItem(stock=gtk.STOCK_COPY, sensitive=False) if is_dir: self.__appendMenuItem(stock=gtk.STOCK_PASTE, sensitive=False) self.__appendSeperator() self.__appendMenuItem(menu0008, sensitive=False) self.__appendSeperator() self.__appendMenuItem(stock=gtk.STOCK_DELETE, callback=lambda a: self.__unlink(uri)) pixbuf = None if icon_manager.theme.has_icon(u'gconf-editor'): pixbuf = icon_manager.theme.load_icon(u'gconf-editor', 16, gtk.ICON_LOOKUP_USE_BUILTIN) self.__appendSeperator() self.__appendMenuItem(label=menu0002, pixbuf=pixbuf, callback=lambda a: self.__display_settings()) pixbuf = None icon_manager = None self.popup(None, None, None, event.button, event.time)
def update(self, info): """ Update icon """ [volume, muted, var, card_name, mixer_name] = info vol = volume[0] if (muted): vol = 0 icon = Icons.get_icon_name_by_volume(vol) self.set_from_icon_name(icon) #""" Update tooltip """ tooltip = "<b>%s: %s%s </b>\n<small>%s: %s\n%s: %s</small>" % ( _("Output"), Icons.get_volume_name(vol, muted), var, _("Card"), card_name, _("Mixer"), mixer_name) self.set_tooltip_markup(tooltip)
def main(): urls = [] debug = False if len(sys.argv) > 1: ## If they want help if sys.argv[1] == "-h" or sys.argv[1] == "--help": print_help() return (0) elif sys.argv[1] == "-V" or sys.argv[1] == "--version": print_version() return (0) ## If they're reading URLs from stdin elif sys.argv[1] == '-' or sys.argv[1] == "--stdin": rawUrls = sys.stdin.readlines() for r in rawUrls: urls.append(r.replace(' ', '\n', -1).strip()) ## If they're trying to use debug mode elif sys.argv[1] == "-d" or sys.argv[1] == "--debug": debug = True ## If they're importing URLs elif os.path.exists(sys.argv[1]): try: fin = open(sys.argv[1], "r") rawUrls = fin.readlines() fin.close() for r in rawUrls: urls.append(r.strip()) except (OSError, PermissionError, FileNotFoundError): print("ERROR: Cannot read from '%s'! Aborting." % sys.argv[1]) sys.exit(1) ## Running a bunch of URLs as args else: for arg in sys.argv[1:]: urls.append(arg) app = QApplication(sys.argv) sysInstall = (os.path.expanduser('~') in sys.argv[0]) app.setWindowIcon(Icons().get_icon("application-icon", sysInstall)) win = MainWindow(debug) if debug: print("(Debug mode)") if len(urls) > 0: win.load_urls(urls) sys.exit(app.exec_())
def format(self, volume, muted, var, card_name, mixer_name): """ Format notification body """ message = self.config.get(self.config.get_default_section(), "notify_body") volume = Icons.get_volume_name(volume, muted) message = message.replace('{volume}', '%s%s' % (volume, var)) message = message.replace('{card}', '%s: %s' % (_("Card"), card_name)) message = message.replace('{mixer}', '%s: %s' % (_("Mixer"), mixer_name)) return message
def __init__(self): QtGui.QMainWindow.__init__(self) self.setupUi(self) self.setMaximumHeight(600) self.setMaximumWidth(800) self.icons = Icons() self.SettingsDialog = SettingsDialog(parent=self) self.NewProjectDialog = NewProjectDialog() self.connect_actions() self.connect_filetree() self.connect_icons() self._project_cache = {}
def __init__(self, model: DataFrameModel, df_manager: DataFrameModelManager, **kwargs): QtGui.QMainWindow.__init__(self, parent=kwargs.pop('parent', None)) self.df_manager = df_manager self._widget = DataTableWidget() self._widget.setModel(model) kwargs['parent'] = self self.icons = Icons() self.setupUi(self) self.dialog_rename = None self.dialog_fields_edit = None self.connect_actions() self.connect_icons()
def main(): urls = [] if len(sys.argv) > 1: if sys.argv[1] == "-h" or sys.argv[1] == "--help": print_help() return (0) app = QApplication(sys.argv) app.setWindowIcon(Icons().get_icon("application-icon")) win = MainWindow() sys.exit(app.exec_())
def init_UI(self): ## Just to make life easier get_icon = Icons().get_icon ## List of characters self.listWidget = QListWidget(self) ## Add character button self.addChar = QPushButton(QIcon(get_icon("list-add")), "") self.addChar.setToolTip("Add a character") ## Remove character button self.removeChar = QPushButton(QIcon(get_icon("list-remove")), "") self.removeChar.setToolTip("Remove selected character") ## Bullshit to make qsplitter work self.list = MyListWidget(self) ## Initial template self.template = self.parent.get_template() ## Tab widget self.tabs = QTabWidget() self.load_tabs() ## Tabs start out disabled self.tabs.setDisabled(True) ## Connect it up self.connect_all() ##============= LAYOUTS splitter = QSplitter() splitter.addWidget(self.list) splitter.addWidget(self.tabs) splitter.setSizes([(WINDOW_WIDTH * .25), (WINDOW_WIDTH * .75)]) ## Set the layout hbox = QHBoxLayout() hbox.addWidget(splitter) self.setLayout(hbox)
def show(self): """ Show the notification """ if (not self.info): return duration = self.config.getfloat(self.config.get_default_section(), "notify_timeout") [volume, muted, var, card_name, mixer_name] = self.info volume = volume[0] icon = Icons.get_icon_name_by_volume(volume) body = self.format(volume, muted, var, card_name, mixer_name) hints = {"urgency": dbus.Byte(0), "desktop-entry": dbus.String("volti")} if self.config.getboolean(self.config.get_default_section(), "notify_position") and self.server_capable: hints["x"], hints["y"] = self.get_position() self.last_id = self.notify.Notify('volume', self.last_id, icon, self.title, body, [], hints, duration * 1000)
def __init__(self, settings_ini: (str, SettingsINI)): self.df_manager = DataFrameModelManager() QtGui.QMainWindow.__init__(self) self.setupUi(self) self.icons = Icons() self.dialog_settings = SettingsDialog(settings=settings_ini) self.dialog_merge_purge = MergePurgeDialog(self.df_manager) self.dialog_export = DataFrameModelExportDialog(self.df_manager, parent=self) self.dialog_import = CSVImportDialog(self) self.connect_window_title() self.connect_actions() self.connect_filetree() self.connect_icons() self.connect_settings_dialog() self.current_model = None # Temp cache self.df_windows = {}
def init_UI(self): ## Laziness get_icon = Icons().get_icon self.label = QLabel(self.path) self.pix = None self.iLabel = QLabel() self.btn = QPushButton(QIcon(get_icon("document-open")), "") self.btn.clicked.connect(self.get_image) hbox = QHBoxLayout() hbox.addWidget(self.btn) hbox.addWidget(self.label, 1) vbox = QVBoxLayout() vbox.addLayout(hbox) vbox.addWidget(self.iLabel) self.setLayout(vbox)
class Filechooser(gobject.GObject): __gtype_name__ = 'Filechooser' __gsignals__ = { 'file-activated': (gobject.SIGNAL_RUN_FIRST, None, (str, )), 'selection-changed': (gobject.SIGNAL_RUN_FIRST, None, (str, )), 'filename-editing-started': (gobject.SIGNAL_RUN_FIRST, None, (object, )), 'button-release-event': (gobject.SIGNAL_RUN_FIRST, None, ()), 'error': (gobject.SIGNAL_RUN_FIRST, None, (str, str)) } def __init__(self): gobject.GObject.__init__(self) # Glade setup self.builder = gtk.Builder() self.builder.add_from_file(os.path.join(UIDIR, "filechooser.glade")) self.builder.connect_signals(self) # Retrieve frequently used objects self.nav_box = self.builder.get_object('hbox1') self.eject_column = self.builder.get_object('eject_col') file_adj = self.builder.get_object('scrolledwindow1') self.file_vadj = file_adj.get_vadjustment() self.file_hadj = file_adj.get_hadjustment() # Retrieve data models self.file_liststore = self.builder.get_object("file_liststore") self.bookmark_liststore = self.builder.get_object("bookmark_liststore") # Retrieve treeviews self.file_treeview = self.builder.get_object("file_treeview") self.bookmark_treeview = self.builder.get_object("bookmark_treeview") self.bookmark_treeview.set_row_separator_func(self.bookmark_separator) # Enable DnD TODO DnD is not implemented yet self.file_treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, \ [('text/plain', 0, 0)], gtk.gdk.ACTION_MOVE | gtk.gdk.ACTION_COPY) self.file_treeview.enable_model_drag_dest([('text/plain', 0, 0)], \ gtk.gdk.ACTION_COPY) # Connect callbacks to VolumeMonitor self.mounts = gio.VolumeMonitor() self.mounts.connect('mount-added', self.on_mount_added) self.mounts.connect('mount-removed', self.on_mount_removed) # Initialize objects self.ok_cancel_dialog = Dialogs(DialogTypes.OK_CANCEL) self.bookmarks = BookMarks() self.icons = Icons(gtk.icon_theme_get_default()) # Initialize places home = os.environ['HOME'] desktop = os.path.expanduser("~/Desktop") self.places = [home, desktop] # Initialize variables self._cur_dir = desktop self._old_dir = " " self._filters = {} self._filter = '' self._files = [] self._show_hidden = False self._hidden_exts = ['.desktop'] self._copy = True self._selection = None self.nav_btn_list = [] self.nav_btn_path_dict = {} # Initialize self._init_nav_buttons() # Have to do this once realized so sizes will have been allocated def on_vbox1_realize(self, widget): self._update_bookmarks() self._fill_file_liststore(self._cur_dir) def _init_nav_buttons(self): box = self.nav_box btn_list = self.nav_btn_list btn_dict = self.nav_btn_path_dict for i in range(10): btn = gtk.Button() btn.connect('clicked', self.on_nav_btn_clicked) btn.set_can_focus(False) btn.set_use_underline(False) btn_list.append(btn) box.pack_start(btn, False, False, 0) btn_dict[btn] = '' def _update_nav_buttons(self, path=None): if path is None: path = self._cur_dir places = path.split('/')[1:] path = '/' for btn in self.nav_btn_list: btn.hide() w_needed = 0 for i, place in enumerate(places): btn = self.nav_btn_list[i] btn.set_label(place) path = os.path.join(path, place) self.nav_btn_path_dict[btn] = path btn.show() w_needed += btn.size_request()[0] w_allowed = self.nav_box.get_allocation()[2] if w_needed > w_allowed: self.builder.get_object('goto_root').hide() self.builder.get_object('arrow_left').show() else: self.builder.get_object('goto_root').show() self.builder.get_object('arrow_left').hide() count = 0 while w_needed > w_allowed: btn = self.nav_btn_list[count] w_needed -= btn.size_request()[0] btn.hide() count += 1 def on_nav_btn_clicked(self, widget, data=None): path = self.nav_btn_path_dict[widget] if path != self._cur_dir: self._fill_file_liststore(path) def on_goto_root_clicked(self, widget, data=None): self._fill_file_liststore('/') # HACK for now def on_arrow_left_clicked(self, widget, data=None): self.up_one_dir() def on_arrow_right_clicked(self, widget, data=None): pass def _fill_file_liststore(self, path=None): model = self.file_liststore model.clear() self.current_selection = None if path: self._cur_dir = path #os.path.realpath(path) # Reset scrollbars since display has changed self.file_vadj.set_value(0) self.file_hadj.set_value(0) files = [] folders = [] if self._filter in self._filters: exts = self._filters[self._filter] else: exts = '' dirs = os.listdir(self._cur_dir) for obj in dirs: if obj[0] == '.' and not self._show_hidden: continue path = os.path.join(self._cur_dir, obj) if os.path.islink(path): path = os.readlink(path) if os.path.isdir(path): folders.append(obj) elif os.path.isfile(path): ext = os.path.splitext(obj)[1] if '*' in exts and not ext in self._hidden_exts: files.append(obj) elif '*{0}'.format(ext) in exts: files.append(obj) folders.sort(key=str.lower, reverse=False) for fname in folders: fpath = os.path.join(self._cur_dir, fname) icon = self.icons.get_for_directory(fpath) model.append([0, icon, fname, None, None]) files.sort(key=str.lower, reverse=False) for fname in files: fpath = os.path.join(self._cur_dir, fname) icon = self.icons.get_for_file(fname) size, date = self._get_file_data(fpath) model.append([0, icon, fname, size, date]) self._update_nav_buttons() def _get_file_data(self, fpath): size = os.path.getsize(fpath) if size >= 1E9: size_str = "{:.1f} GB".format(size / 1E9) elif size >= 1E6: size_str = "{:.1f} MB".format(size / 1E6) elif size >= 1E3: size_str = "{:.1f} KB".format(size / 1E3) else: size_str = "{} bytes".format(size) tstamp = os.path.getmtime(fpath) date_str = datetime.fromtimestamp(tstamp).strftime("%m/%d/%y %X") return size_str, date_str def on_select_toggled(self, widget, path): model = self.file_liststore model[path][0] = not model[path][0] def on_filechooser_treeview_cursor_changed(self, widget): path = widget.get_cursor()[0] # Prevent emiting selection changed on double click if path == self.current_selection: return self.current_selection = path fname = self.file_liststore[path][2] fpath = os.path.join(self._cur_dir, fname) self.emit('selection-changed', fpath) def on_filechooser_treeview_row_activated(self, widget, path, colobj): fname = self.file_liststore[path][2] fpath = os.path.join(self._cur_dir, fname) if os.path.isfile(fpath): self.emit('file-activated', fpath) elif os.path.isdir(fpath): self._fill_file_liststore(fpath) def on_file_name_editing_started(self, renderer, entry, row): self.emit('filename-editing-started', entry) def on_file_name_edited(self, widget, row, new_name): model = self.file_liststore old_name = model[row][2] old_path = os.path.join(self._cur_dir, old_name) new_path = os.path.join(self._cur_dir, new_name) if old_name == new_name: return if not os.path.exists(new_path): msg = "Renamed {} to {}".format(old_name, new_name) log.info(msg) self.info(msg) os.rename(old_path, new_path) model[row][2] = new_name else: msg = "Destination file already exists, won't rename" log.warning(msg) self.warn(msg) # TODO add overwrite confirmation dialog def on_file_treeview_button_release_event(self, widget, data=None): self.emit('button-release-event') # ======================================= # Methods to be called externally # ======================================= # Get filechooser object to embed in main window def get_filechooser_widget(self): return self.builder.get_object('vbox1') # Add filter by name and list of extensions to display def add_filter(self, name, ext): self._filters[name] = ext # Delete filter by name def remove_filter(self, name): if name in self._filters: del self._filters[name] return True return False # Set current filter by name def set_filter(self, name): if name in self._filters: self._filter = name self._fill_file_liststore() return True return False # Get current filter def get_filter(self): if self._filter in self._filters: return [self._filter, self._filters[self._filter]] return None # Get names of all specified filters def get_filters(self): filters = [] for filter in self._filters: filters.append(filter) return filters # Get whether hidden files are shown def get_show_hidden(self): return self._show_hidden # Set whether hidden files are shown def set_show_hidden(self, setting): self._show_hidden = setting # Get the path of the current display directory def get_current_folder(self): return self._cur_dir # Set current display directory to path def set_current_folder(self, fpath): if os.path.exists(fpath): self._fill_file_liststore(fpath) return True return False # Get absolute path at cursor def get_path_at_cursor(self): path = self.file_treeview.get_cursor()[0] if path is not None: fname = self.file_liststore[path][2] fpath = os.path.join(self._cur_dir, fname) return fpath return None # Set cursor at path def set_cursor_at_path(self, fpath): model = self.file_liststore tree = self.file_treeview if not os.path.exists(fpath): return False fpath, fname = os.path.split(fpath) if fpath != self._cur_dir: self._fill_file_liststore(fpath) for row in range(len(model)): if model[row][2] == fname: tree.set_cursor(row) return True return False # Get paths for selected def get_selected(self): model = self.file_liststore paths = [] for row in range(len(model)): if model[row][0] == 1: fpath = os.path.join(self._cur_dir, model[row][2]) paths.append(fpath) if len(paths) == 0: return None return paths # Check checkbox at file path def set_selected(self, fpath): model = self.file_liststore tree = self.file_treeview if not os.path.exists(fpath): return False fpath, fname = os.path.split(fpath) if fpath != self._cur_dir: self._fill_file_liststore(fpath) for row in range(len(model)): if model[row][2] == fname: model[row][0] = 1 return True return False # Check all checkboxes in current display directory def select_all(self, fpath=None): model = self.file_liststore if fpath is not None: if os.path.isdir(fpath): self._fill_file_liststore(fpath) else: return False for row in range(len(model)): model[row][0] = 1 return True # Uncheck all checkboxes in current display directory def unselect_all(self): model = self.file_liststore for row in range(len(model)): model[row][0] = 0 # Get paths to current mounts def get_mounts(self): mounts = self.mounts.get_mounts() paths = [] for mount in mounts: path = mount.get_root().get_path() paths.append(path) return paths # Get list of user bookmarks def get_bookmarks(self): return self.bookmarks.get() # Add bookmark def add_bookmark(self, path): if not path in self.places: self.bookmarks.add(path) self._update_bookmarks() # Remove bookmark def remove_bookmark(self, path): if not path in self.places: self.bookmarks.remove(path) self._update_bookmarks() # Clear all bookmarks def clear_bookmarks(self): self.bookmarks.clear() self._update_bookmarks() # Display parent of current directory def up_one_dir(self): path = os.path.dirname(self._cur_dir) self._fill_file_liststore(path) # Cut selected files def cut_selected(self): files = self.get_selected() if files is None: log.error("No files selected to cut") return False self._files = files self._copy = False log.debug("Files to cut: {}".format(files)) return True # Copy selected files def copy_selected(self): files = self.get_selected() if files is None: log.error("No files selected to copy") return False self._files = files self._copy = True log.debug("Files to copy: {}".format(files)) return True # Paste previously cut/copied files to current directory def paste(self): src_list = self._files if src_list is None: return False dst_dir = self._cur_dir if self._copy: for src in self._files: self._copy_file(src, dst_dir) elif not self._copy: for src in self._files: self._move_file(src, dst_dir) self._files = None self._fill_file_liststore() return True # Save file as, if path is specified it will be saved in that directory def save_as(self, path=None): model = self.file_liststore tree = self.file_treeview if path is None: path = self.get_selected()[0] if not os.path.exists(path) or path is None: return False fpath, fname = os.path.split(path) new_name = self._copy_file(path, fdir) for row in range(len(model)): if model[row][2] == new_name: break focus_column = self.builder.get_object('col_file_name') model[row][0] = 1 tree.set_cursor(row, focus_column, True) # Create a new folder in the current directory def new_folder(self): model = self.file_liststore tree = self.file_treeview name = "New Folder" count = 1 while os.path.exists(os.path.join(self._cur_dir, name)): name = 'New Folder {0}'.format(count) count += 1 path = os.path.join(self._cur_dir, name) os.makedirs(path) self._fill_file_liststore() for row in range(len(model)): if model[row][2] == name: break focus_column = self.builder.get_object('col_file_name') model[row][0] = 1 tree.set_cursor(row, focus_column, True) # Move selected files to trash (see file_util code at end) def delete_selected(self): paths = self.get_selected() if paths is None: return num = len(paths) for path in paths: info = move2trash(path) self._fill_file_liststore() # Show ERROR/INFO message at bottom of screen self.emit('error', info[0], info[1]) # ======================================= # Drag and Drop TODO # ======================================= def on_file_treeview_drag_begin(self, data, som): log.debug("drag {0} {1}".format(data, som)) def on_file_treeview_drag_data_received(self): log.debug("got drag") def drag_data_received_cb(self, treeview, context, x, y, selection, info, timestamp): drop_info = treeview.get_dest_row_at_pos(x, y) log.debug("got drag") if drop_info: model = treeview.get_model() path, position = drop_info data = selection.data # do something with the data and the model log.debug("{0} {1} {2}".format(model, path, data)) return # ======================================= # Bookmark treeview # ======================================= def on_mount_added(self, volume, mount): path = mount.get_root().get_path() name = os.path.split(path)[1] msg = 'External storage device "{}" mounted'.format(name) log.info(msg) self.info(msg) self._update_bookmarks() def on_mount_removed(self, volume, mount): path = mount.get_root().get_path() name = os.path.split(path)[1] msg = 'External storage device "{}" removed'.format(name) log.info(msg) self.info(msg) if self._cur_dir.startswith(path): self.file_liststore.clear() self._update_nav_buttons('') self._update_bookmarks() def on_bookmark_treeview_cursor_changed(self, widget): model = self.bookmark_liststore path, column = widget.get_cursor() fpath = model[path][2] if column == self.eject_column and model[path][3] == True: os.system('eject "{0}"'.format(fpath)) if fpath == self._cur_dir: self.file_liststore.clear() return self._fill_file_liststore(fpath) def on_add_bookmark_button_release_event(self, widget, data=None): path = self.file_treeview.get_cursor()[0] if path is None: fpath = self._cur_dir else: fname = self.file_liststore[path][2] fpath = os.path.join(self._cur_dir, fname) if not os.path.isdir(fpath): return self.add_bookmark(fpath) def on_remove_bookmark_button_release_event(self, widget, data=None): path = self.bookmark_treeview.get_cursor()[0] if path is None: return fpath = self.bookmark_liststore[path][2] self.remove_bookmark(fpath) def _update_bookmarks(self): places = sorted(self.places, key=len, reverse=False) mounts = sorted(self.get_mounts(), key=self.sort, reverse=False) bookmarks = sorted(self.bookmarks.get(), key=self.sort, reverse=False) model = self.bookmark_liststore model.clear() # Add the places for path in places: name = os.path.split(path)[1] icon = self.icons.get_for_directory(path) model.append([icon, name, path, False]) # Add the mounts for path in mounts: name = os.path.split(path)[1] icon = self.icons.get_for_device('USBdrive') model.append([icon, name, path, True]) # Add the seperator model.append([None, None, None, False]) # Add the bookmarks for bookmark in bookmarks: path, name = bookmark if not os.path.exists(path): continue if name == '': name = os.path.split(path)[1] icon = self.icons.get_for_directory(path) model.append([icon, name, path, False]) # Generate sort key based on file basename def sort(self, path): return os.path.basename(path[0]).lower() # If name is None row should be a separator def bookmark_separator(self, model, iter): return self.bookmark_liststore.get_value(iter, 1) is None # ======================================= # File utilities # ======================================= def _copy_file(self, src, dst_dir): src_dir, src_name = os.path.split(src) dst_name = src_name # find a unique copy name if src_dir == dst_dir: name, ext = os.path.splitext(dst_name) if '_copy' in name: name = name.rpartition('_copy')[0] count = 1 while os.path.exists(os.path.join(dst_dir, dst_name)): dst_name = '{0}_copy{1}{2}'.format(name, count, ext) count += 1 dst = os.path.join(dst_dir, dst_name) if os.path.exists(dst): text = "Destination already exists! \n Overwrite {}?".format( dst_name) overwrite = self.ok_cancel_dialog.run(text) if not overwrite: msg = "User selected not to overwrite {}".format(dst_name) log.info(msg) self.info(msg) return msg = 'Copying "{0}" to "{1}"'.format(src_name, dst_dir) log.info(msg) self.info(msg) if os.path.isfile(src): shutil.copy2(src, dst) else: shutil.copytree(src, dst) self._fill_file_liststore() return dst_name def _move_file(self, src, dst_dir): src_dir, src_name = os.path.split(src) if src_dir == dst_dir: msg = "MOVE ERROR: Source and destination are the same" log.error(msg) self.error(msg) return dst = os.path.join(dst_dir, src_name) if os.path.exists(dst): text = "Destination already exists! \n Overwrite {}?".format( src_name) overwrite = self.ok_cancel_dialog.run(text) if not overwrite: msg = 'User selected not to overwrite "{}"'.format(src_name) log.info(msg) self.info(msg) return msg = 'Moving "{0}" to "{1}"'.format(src_name, dst_dir) log.info(msg) self.info(msg) shutil.move(src, dst) # Shortcut methods to emit errors and print to terminal def error(self, text): self.emit('error', 'ERROR', text) def warn(self, text): self.emit('error', 'WARN', text) def info(self, text): self.emit('error', 'INFO', text)
class FileChooser(Gtk.Bin): __gtype_name__ = 'FileChooser' __gsignals__ = { 'file-activated': (GObject.SignalFlags.RUN_FIRST, None, (str, )), 'selection-changed': (GObject.SignalFlags.RUN_FIRST, None, (str, )) } def __init__(self, widget_window): Gtk.Bin.__init__(self) self.widget_window = widget_window # Glade setup self.builder = Gtk.Builder() self.builder.add_from_file(os.path.join(UIDIR, "filechooser.glade")) self.builder.connect_signals(self) self.builder.get_object = self.builder.get_object self.add(self.builder.get_object('filechooser')) # Retrieve frequently used objects self.nav_box = self.builder.get_object('nav_box') self.nav_btn_box = self.builder.get_object('nav_btn_box') file_adj = self.builder.get_object('fileview') self.file_vadj = file_adj.get_vadjustment() self.file_hadj = file_adj.get_hadjustment() # Retrieve data models self.file_liststore = self.builder.get_object("file_liststore") # Retrieve treeviews self.file_treeview = self.builder.get_object("file_treeview") self.bookmark_listbox = self.builder.get_object("bookmark_listbox") # Enable DnD ToDo implement DnD self.file_treeview.enable_model_drag_source( Gdk.ModifierType.BUTTON1_MASK, [('text/plain', 0, 0)], Gdk.DragAction.MOVE | Gdk.DragAction.COPY) self.file_treeview.enable_model_drag_dest([('text/plain', 0, 0)], Gdk.DragAction.COPY) # Connect callbacks to VolumeMonitor self.mounts = Gio.VolumeMonitor.get() self.mounts.connect('mount-added', self.on_mount_added) self.mounts.connect('mount-removed', self.on_mount_removed) # Initialize helpers self.bookmarks = BookMarks() self.icons = Icons(Gtk.IconTheme.get_default()) # Initialize places self.userdirs = UserDirectories() desktop = self.userdirs.get_XDG_directory('XDG_DESKTOP_DIR') home = self.userdirs.get_home_directory() self.places = [home, desktop] # Initialize variables self._cur_dir = None self._old_dir = '' self._filters = {} self._filter = None self._files = [] self._show_hidden = False self._hidden_exts = ['.desktop'] self._copy = True self._selection = None self.nav_btn_list = [] self.nav_btn_path_dict = {} self.eject_btn_path_dict = {} # Initialize self._init_nav_buttons() self.show_all() # Have to do this once realized so sizes will have been allocated def on_filechooser_realize(self, widget): self._update_bookmarks() self._fill_file_liststore(self._cur_dir) def _init_nav_buttons(self): # FixMe this needs a lot of work. Try to copy this implementation # https://searchcode.com/codesearch/view/22668315/ box = self.nav_btn_box box.get_style_context().add_class(Gtk.STYLE_CLASS_LINKED) arrow_left = Gtk.Arrow.new(Gtk.ArrowType.LEFT, Gtk.ShadowType.NONE) self.arrow_btn_left = Gtk.Button() self.arrow_btn_left.add(arrow_left) box.add(self.arrow_btn_left) self.btn_goto_root = Gtk.Button.new_from_icon_name( 'gtk-harddisk', Gtk.IconSize.LARGE_TOOLBAR) self.btn_goto_root.connect('pressed', self.on_goto_root_clicked) box.add(self.btn_goto_root) btn_list = self.nav_btn_list btn_dict = self.nav_btn_path_dict for i in range(10): btn = Gtk.Button() btn.set_hexpand(False) btn.connect('clicked', self.on_nav_btn_clicked) btn.set_can_focus(False) btn.set_use_underline(False) btn_list.append(btn) box.add(btn) btn_dict[btn] = '' # arrow_right = Gtk.Arrow.new(Gtk.ArrowType.RIGHT, Gtk.ShadowType.NONE) # self.arrow_btn_right = Gtk.Button() # self.arrow_btn_right.add(arrow_right) # box.add(self.arrow_btn_right) box.show_all() def _update_nav_buttons(self, path=None): for btn in self.nav_btn_list: btn.hide() if path is None: path = self._cur_dir if len(path) == 1: return places = path.split('/')[1:] path = '/' w_needed = 0 w_allowed = self.nav_btn_box.get_allocated_width() for i, place in enumerate(places): btn = self.nav_btn_list[i] btn.set_label(place) path = os.path.join(path, place) self.nav_btn_path_dict[btn] = path btn.show() w_needed += btn.get_allocated_width() if w_needed > w_allowed: self.btn_goto_root.hide() self.arrow_btn_left.show() else: self.btn_goto_root.show() self.arrow_btn_left.hide() count = 0 while w_needed > w_allowed: btn = self.nav_btn_list[count] w_needed -= btn.get_allocated_width() btn.hide() count += 1 def on_nav_btn_clicked(self, widget, data=None): path = self.nav_btn_path_dict[widget] if path != self._cur_dir: self._fill_file_liststore(path) def on_goto_root_clicked(self, widget, data=None): self._fill_file_liststore('/') # HACK for now def on_arrow_left_clicked(self, widget, data=None): self.up_one_dir() def on_arrow_right_clicked(self, widget, data=None): pass def _fill_file_liststore(self, path=None): model = self.file_liststore model.clear() self.selected_row = None if path: self._cur_dir = path # Reset scrollbars since display has changed self.file_vadj.set_value(0) self.file_hadj.set_value(0) if self._cur_dir is None: self._cur_dir = self.userdirs.get_XDG_directory('XDG_DESKTOP_DIR') files = [] folders = [] if self._filter: exts = self._filters[self._filter] else: exts = '*' # Don't filter names = os.listdir(self._cur_dir) for name in names: if name[0] == '.' and not self._show_hidden: continue path = os.path.join(self._cur_dir, name) if os.path.islink(path): path = os.readlink(path) if os.path.isdir(path): folders.append(name) elif os.path.isfile(path): ext = os.path.splitext(name)[1] if '*' in exts or ext in exts and not ext in self._hidden_exts: files.append(name) folders.sort(key=str.lower, reverse=False) for fname in folders: fpath = os.path.join(self._cur_dir, fname) icon = self.icons.get_for_directory(fpath) model.append([0, icon, fname, None, None]) files.sort(key=str.lower, reverse=False) for fname in files: fpath = os.path.join(self._cur_dir, fname) icon = self.icons.get_for_file(fname) size, date = self._get_file_data(fpath) model.append([0, icon, fname, size, date]) self._update_nav_buttons() self.emit('selection-changed', self._cur_dir) # If dir is in bookmarks, select the bookmark for row in self.bookmark_listbox.get_children(): bookmark_path = row.get_tooltip_text() if bookmark_path == self._cur_dir: self.bookmark_listbox.select_row(row) break else: self.bookmark_listbox.unselect_all() # No file selected yet, so desensitize edit buttons self.builder.get_object('edit_button').set_sensitive(False) self.builder.get_object('cut_button').set_sensitive(False) self.builder.get_object('copy_button').set_sensitive(False) self.builder.get_object('delete_button').set_sensitive(False) def _get_file_data(self, fpath): size = os.path.getsize(fpath) if size >= 1E9: size_str = "{:.1f} GB".format(size / 1E9) elif size >= 1E6: size_str = "{:.1f} MB".format(size / 1E6) elif size >= 1E3: size_str = "{:.1f} KB".format(size / 1E3) else: size_str = "{} bytes".format(size) tstamp = os.path.getmtime(fpath) date_str = datetime.fromtimestamp(tstamp).strftime("%m/%d/%y %X") return size_str, date_str def count_lines(self, filename): lines = 0 buf_size = 1024 * 1024 with open(filename) as fh: read_f = fh.read buf = read_f(buf_size) while buf: lines += buf.count('\n') buf = read_f(buf_size) return lines + 1 def on_select_toggled(self, widget, path): model = self.file_liststore model[path][0] = not model[path][0] def on_file_treeview_key_press_event(self, widget, event): kv = event.keyval # Events that don't need to know about modifiers if kv == Gdk.KEY_Escape: self.file_treeview.get_selection().unselect_all() self.builder.get_object('edit_button').set_sensitive(False) self.builder.get_object('cut_button').set_sensitive(False) self.builder.get_object('copy_button').set_sensitive(False) self.builder.get_object('delete_button').set_sensitive(False) return True elif kv == Gdk.KEY_Delete: self.delete_selected() return True elif kv == Gdk.KEY_F2: self.edit_selected() return True # Handle other events # Determine the actively pressed modifier modifier = event.get_state() & Gtk.accelerator_get_default_mod_mask() # Bool of Control or Shift modifier states control = modifier == Gdk.ModifierType.CONTROL_MASK shift = modifier == Gdk.ModifierType.SHIFT_MASK if control and kv == Gdk.KEY_c: return self.copy_selected() elif control and kv == Gdk.KEY_x: return self.cut_selected() elif control and kv == Gdk.KEY_v: return self.paste() def on_filechooser_treeview_cursor_changed(self, widget): row = widget.get_cursor()[0] # Prevent emitting selection changed on double click if row == self.selected_row or row is None: return self.selected_row = row fname = self.file_liststore[row][2] fpath = os.path.join(self._cur_dir, fname) self.emit('selection-changed', fpath) self.builder.get_object('edit_button').set_sensitive(True) self.builder.get_object('cut_button').set_sensitive(True) self.builder.get_object('copy_button').set_sensitive(True) self.builder.get_object('delete_button').set_sensitive(True) def on_filechooser_treeview_row_activated(self, widget, path, colobj): fname = self.file_liststore[path][2] fpath = os.path.join(self._cur_dir, fname) if os.path.isfile(fpath): self.emit('file-activated', fpath) elif os.path.isdir(fpath): self._fill_file_liststore(fpath) else: # If neither, probably does not exist, so reload self._fill_file_liststore() def on_file_name_editing_started(self, renderer, entry, row): keyboard.show(entry) def on_file_name_edited(self, widget, row, new_name): model = self.file_liststore model[row][0] = 0 old_name = model[row][2] old_path = os.path.join(self._cur_dir, old_name) new_path = os.path.join(self._cur_dir, new_name) if old_name == new_name: return if not os.path.exists(new_path): os.rename(old_path, new_path) msg = 'Renamed "{}" to "{}"'.format(old_name, new_name) log.info(msg) self.widget_window.show_info(msg, 2) model[row][2] = new_name else: msg = "Destination file already exists, won't rename" log.warning(msg) self.widget_window.show_warning(msg) # ======================================= # Methods to be called externally # ======================================= # Add filter by name def add_filter(self, name, exts): self._filters[name] = [ext.replace('*.', '.') for ext in exts] # Delete filter by name def delete_filter(self, name): if name in self._filters: del self._filters[name] if self._filter == name: self._filter = None return True return False # Set current filter by name def set_filter(self, name): if name is None: self._filter = None elif name in self._filters: self._filter = name self._fill_file_liststore() # Get current filter def get_filter(self): if self._filter in self._filters: return ['*' + ext for ext in self._filters[self._filter]] return None # Get names of all specified filters def get_filters(self): filters = [] for filter in self._filters: filters.append(filter) return filters # Get whether hidden files are shown def get_show_hidden(self): return self._show_hidden # Set whether hidden files are shown def set_show_hidden(self, setting): self._show_hidden = setting # Get the path of the current display directory def get_current_folder(self): return self._cur_dir # Set current display directory to path def set_current_folder(self, fpath): # fpath = fpath.rstrip('/') if os.path.exists(fpath): self._fill_file_liststore(fpath) log.info('Setting the current folder to "{}"'.format(fpath)) return True log.error( 'Can not set current folder to "{}", folder does not exist'.format( fpath)) return False # Get absolute path at cursor def get_path_at_cursor(self): path = self.file_treeview.get_cursor()[0] if path is not None: fname = self.file_liststore[path][2] fpath = os.path.join(self._cur_dir, fname) return fpath return None # Set cursor at path def set_cursor_at_path(self, fpath): model = self.file_liststore tree = self.file_treeview if not os.path.exists(fpath): return False fpath, fname = os.path.split(fpath) if fpath != self._cur_dir: self._fill_file_liststore(fpath) for row in range(len(model)): if model[row][2] == fname: tree.set_cursor(row) return True return False # Get paths for selected def get_selected(self): model, rows = self.file_treeview.get_selection().get_selected_rows() if not rows: return paths = [] for row in rows: fpath = os.path.join(self._cur_dir, model[row.to_string()][2]) paths.append(fpath) return paths # Check checkbox at file path def set_selected(self, fpath): model = self.file_liststore tree = self.file_treeview if not os.path.exists(fpath): return False fpath, fname = os.path.split(fpath) if fpath != self._cur_dir: self._fill_file_liststore(fpath) for row in range(len(model)): if model[row][2] == fname: model[row][0] = 1 return True return False # Check all checkboxes in current display directory def select_all(self, fpath=None): model = self.file_liststore if fpath is not None: if os.path.isdir(fpath): self._fill_file_liststore(fpath) else: return False for row in range(len(model)): model[row][0] = 1 return True # Uncheck all checkboxes in current display directory def unselect_all(self): model = self.file_liststore for row in range(len(model)): model[row][0] = 0 # Get paths to current mounts def get_mounts(self): mounts = self.mounts.get_mounts() paths = [] for mount in mounts: path = mount.get_root().get_path() name = mount.get_name() paths.append([path, name, mount]) return paths # Get list of user bookmarks def get_bookmarks(self): return self.bookmarks.get() # Add bookmark def add_bookmark(self, path): if not path in self.places: self.bookmarks.add(path) self._update_bookmarks() # Remove bookmark def remove_bookmark(self, path): if not path in self.places: self.bookmarks.remove(path) self._update_bookmarks() # Clear all bookmarks def clear_bookmarks(self): self.bookmarks.clear() self._update_bookmarks() # Display parent of current directory def up_one_dir(self): path = os.path.dirname(self._cur_dir) self._fill_file_liststore(path) # Cut selected files def cut_selected(self, widegt=None, data=None): files = self.get_selected() if not files: log.error("No files selected to cut") return False self._files = files self._copy = False log.debug("Files to cut: {}".format(files)) self.builder.get_object('paste_button').set_sensitive(True) return True # Copy selected files def copy_selected(self, widegt=None, data=None): files = self.get_selected() if files is None: log.error("No files selected to copy") return False self._files = files self._copy = True log.debug("Files to copy: {}".format(files)) self.builder.get_object('paste_button').set_sensitive(True) return True # Paste previously cut/copied files to current directory def paste(self, widegt=None, data=None): src_list = self._files if src_list is None: return False dst_dir = self._cur_dir if self._copy: for src in self._files: self._copy_file(src, dst_dir) elif not self._copy: for src in self._files: self._move_file(src, dst_dir) self._files = None self._fill_file_liststore() self.builder.get_object('paste_button').set_sensitive(False) return True # Save file as, if path is specified it will be saved in that directory def save_as(self, path=None): model = self.file_liststore tree = self.file_treeview if path is None: path = self.get_selected()[0] if not os.path.exists(path) or path is None: return False fpath, fname = os.path.split(path) new_name = self._copy_file(path, fdir) for row in range(len(model)): if model[row][2] == new_name: break focus_column = self.builder.get_object('col_file_name') model[row][0] = 1 tree.set_cursor(row, focus_column, True) # Create a new folder in the current directory def new_folder(self, widegt=None, data=None): model = self.file_liststore tree = self.file_treeview name = "New Folder" count = 1 while os.path.exists(os.path.join(self._cur_dir, name)): name = 'New Folder {0}'.format(count) count += 1 path = os.path.join(self._cur_dir, name) os.makedirs(path) self._fill_file_liststore() for row in range(len(model)): if model[row][2] == name: break focus_column = self.builder.get_object('col_file_name') model[row][0] = 1 tree.set_cursor(row, focus_column, True) # Create a new folder in the current directory def new_file(self, widegt=None, data=None): model = self.file_liststore tree = self.file_treeview name = "New file" count = 1 while os.path.exists(os.path.join(self._cur_dir, name)): name = 'New Folder {0}'.format(count) count += 1 path = os.path.join(self._cur_dir, name) with open(path, 'w') as fh: pass self._fill_file_liststore() for row in range(len(model)): if model[row][2] == name: break focus_column = self.builder.get_object('col_file_name') model[row][0] = 1 tree.set_cursor(row, focus_column, True) def edit_selected(self, widget=None, data=None): row = self.file_treeview.get_cursor()[0] if not row: return model = self.file_liststore tree = self.file_treeview focus_column = self.builder.get_object('col_file_name') model[row][0] = 1 tree.set_cursor(row, focus_column, True) # Move selected files to trash (see file_util code at end) def delete_selected(self, widegt=None, data=None): paths = self.get_selected() if paths is None: return num = len(paths) for path in paths: result, msg = move2trash(path) self._fill_file_liststore() if result == 'INFO': self.widget_window.show_info(msg, 2) else: self.widget_window.show_error(msg) # ======================================= # Drag and Drop TODO # ======================================= def on_file_treeview_drag_begin(self, data, som): log.debug("drag {0} {1}".format(data, som)) def on_file_treeview_drag_data_received(self): log.debug("got drag") def drag_data_received_cb(self, treeview, context, x, y, selection, info, timestamp): drop_info = treeview.get_dest_row_at_pos(x, y) log.debug("got drag") if drop_info: model = treeview.get_model() path, position = drop_info data = selection.data # do something with the data and the model log.debug("{0} {1} {2}".format(model, path, data)) return # ======================================= # Bookmark treeview # ======================================= def on_mount_added(self, volume, mount): path = mount.get_root().get_path() name = os.path.split(path)[1] msg = 'External storage device "{}" mounted'.format(name) log.info(msg) self.widget_window.show_info(msg, 2) self._update_bookmarks() def on_mount_removed(self, volume, mount): path = mount.get_root().get_path() name = os.path.split(path)[1] msg = 'External storage device "{}" removed'.format(name) log.info(msg) self.widget_window.show_info(msg, 2) if self._cur_dir.startswith(path): self.file_liststore.clear() self._update_nav_buttons('') self._update_bookmarks() def on_eject_clicked(self, widget): mount = self.eject_btn_path_dict[widget] path = mount.get_root().get_path() name = mount.get_name() mount.eject(0, None, self.on_eject_finished) def on_eject_finished(self, mount, result): msg = 'Safe to remove external storage device "{}"'.format( mount.get_name()) log.info(msg) self.widget_window.show_info(msg, 2) def on_add_bookmark_button_release_event(self, widget, data=None): path = self.file_treeview.get_cursor()[0] if path is None: fpath = self._cur_dir else: fname = self.file_liststore[path][2] fpath = os.path.join(self._cur_dir, fname) if not os.path.isdir(fpath): return self.add_bookmark(fpath) def on_remove_bookmark_button_release_event(self, widget, data=None): row = self.bookmark_listbox.get_selected_row() if row is None: return path = row.get_tooltip_text() self.bookmark_listbox.remove(row) self.bookmarks.remove(path) def _update_bookmarks(self): ext_media = sorted(self.get_mounts(), key=self.sort, reverse=False) bookmarks = sorted(self.bookmarks.get(), key=self.sort, reverse=False) for child in self.bookmark_listbox.get_children(): self.bookmark_listbox.remove(child) # Add the places for path in self.places: icon = self.icons.get_for_directory(path) self.add_listbox_row(icon, path) # Add the mounts self.eject_btn_path_dict = {} icon = self.icons.get_for_device('USBdrive') for device in ext_media: path, name, mount = device if mount.can_eject(): self.add_listbox_row(icon, path, name, mount) else: self.add_listbox_row(icon, path, name) # Add the seperator row = Gtk.ListBoxRow() row.set_selectable(False) separator = Gtk.Separator() row.add(separator) self.bookmark_listbox.add(row) # Add the bookmarks for bookmark in bookmarks: path, name = bookmark if not os.path.exists(path): continue icon = self.icons.get_for_directory(path) self.add_listbox_row(icon, path, name) self.bookmark_listbox.show_all() def add_listbox_row(self, icon, path, name=None, mount=None): if not name or name == '': name = os.path.split(path)[1] row = Gtk.ListBoxRow() row.set_tooltip_text(path) hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) row.add(hbox) # Add icon image = Gtk.Image.new_from_pixbuf(icon) hbox.pack_start(image, False, False, 0) # Add label label = Gtk.Label() label.set_text(name) label.set_xalign(0) hbox.pack_start(label, True, True, 4) # Add media eject button if mount is not None: icon = self.icons.get_for_device('media-eject') image = Gtk.Image.new_from_pixbuf(icon) btn = Gtk.Button() self.eject_btn_path_dict[btn] = mount btn.connect('clicked', self.on_eject_clicked) btn.set_name('eject') btn.set_image(image) hbox.pack_start(btn, False, False, 0) self.bookmark_listbox.add(row) # Generate sort key based on file basename def sort(self, location): path = location[0] name = location[1] if name is None: return os.path.basename(path).lower() return name def on_bookmark_activated(self, widget, data=None): path = data.get_tooltip_text() self._fill_file_liststore(path) # ======================================= # File utilities # ======================================= def _copy_file(self, src, dst_dir): src_dir, src_name = os.path.split(src) dst_name = src_name # find a unique copy name if src_dir == dst_dir: name, ext = os.path.splitext(dst_name) if '_copy' in name: name = name.rpartition('_copy')[0] count = 1 while os.path.exists(os.path.join(dst_dir, dst_name)): dst_name = '{0}_copy{1}{2}'.format(name, count, ext) count += 1 dst = os.path.join(dst_dir, dst_name) if os.path.exists(dst): text = "Destination already exists! \n Overwrite {}?".format( dst_name) overwrite = False #self.ok_cancel_dialog.run(text) if not overwrite: msg = "User selected not to overwrite {}".format(dst_name) log.info(msg) self.widget_window.show_info(msg, 2) return if os.path.isfile(src): shutil.copy2(src, dst) else: shutil.copytree(src, dst) msg = 'Copied "{0}" to "{1}"'.format(src_name, dst_dir) log.info(msg) self.widget_window.show_info(msg, 2) self._fill_file_liststore() return dst_name def _move_file(self, src, dst_dir): src_dir, src_name = os.path.split(src) if src_dir == dst_dir: msg = "MOVE ERROR: Source and destination are the same" log.error(msg) self.widget_window.show_error(msg) return dst = os.path.join(dst_dir, src_name) if os.path.exists(dst): msg = "WARNING: Destination already exists. Overwrite {}?".format( src_name) overwrite = False #self.ok_cancel_dialog.run(text) if not overwrite: msg = 'User selected not to overwrite "{}"'.format(src_name) log.info(msg) self.widget_window.show_info(msg, 2) return msg = 'Moving "{0}" to "{1}"'.format(src_name, dst_dir) log.info(msg) self.widget_window.show_info(msg, 2) shutil.move(src, dst)
def __init__(self, widget_window): Gtk.Bin.__init__(self) self.widget_window = widget_window # Glade setup self.builder = Gtk.Builder() self.builder.add_from_file(os.path.join(UIDIR, "filechooser.glade")) self.builder.connect_signals(self) self.builder.get_object = self.builder.get_object self.add(self.builder.get_object('filechooser')) # Retrieve frequently used objects self.nav_box = self.builder.get_object('nav_box') self.nav_btn_box = self.builder.get_object('nav_btn_box') file_adj = self.builder.get_object('fileview') self.file_vadj = file_adj.get_vadjustment() self.file_hadj = file_adj.get_hadjustment() # Retrieve data models self.file_liststore = self.builder.get_object("file_liststore") # Retrieve treeviews self.file_treeview = self.builder.get_object("file_treeview") self.bookmark_listbox = self.builder.get_object("bookmark_listbox") # Enable DnD ToDo implement DnD self.file_treeview.enable_model_drag_source( Gdk.ModifierType.BUTTON1_MASK, [('text/plain', 0, 0)], Gdk.DragAction.MOVE | Gdk.DragAction.COPY) self.file_treeview.enable_model_drag_dest([('text/plain', 0, 0)], Gdk.DragAction.COPY) # Connect callbacks to VolumeMonitor self.mounts = Gio.VolumeMonitor.get() self.mounts.connect('mount-added', self.on_mount_added) self.mounts.connect('mount-removed', self.on_mount_removed) # Initialize helpers self.bookmarks = BookMarks() self.icons = Icons(Gtk.IconTheme.get_default()) # Initialize places self.userdirs = UserDirectories() desktop = self.userdirs.get_XDG_directory('XDG_DESKTOP_DIR') home = self.userdirs.get_home_directory() self.places = [home, desktop] # Initialize variables self._cur_dir = None self._old_dir = '' self._filters = {} self._filter = None self._files = [] self._show_hidden = False self._hidden_exts = ['.desktop'] self._copy = True self._selection = None self.nav_btn_list = [] self.nav_btn_path_dict = {} self.eject_btn_path_dict = {} # Initialize self._init_nav_buttons() self.show_all()
def __init__(self): gobject.GObject.__init__(self) # Glade setup self.builder = gtk.Builder() self.builder.add_from_file(os.path.join(UIDIR, "filechooser.glade")) self.builder.connect_signals(self) # Retrieve frequently used objects self.nav_box = self.builder.get_object('hbox1') self.eject_column = self.builder.get_object('eject_col') file_adj = self.builder.get_object('scrolledwindow1') self.file_vadj = file_adj.get_vadjustment() self.file_hadj = file_adj.get_hadjustment() # Retrieve data models self.file_liststore = self.builder.get_object("file_liststore") self.bookmark_liststore = self.builder.get_object("bookmark_liststore") # Retrieve treeviews self.file_treeview = self.builder.get_object("file_treeview") self.bookmark_treeview = self.builder.get_object("bookmark_treeview") self.bookmark_treeview.set_row_separator_func(self.bookmark_separator) # Enable DnD TODO DnD is not implemented yet self.file_treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, \ [('text/plain', 0, 0)], gtk.gdk.ACTION_MOVE | gtk.gdk.ACTION_COPY) self.file_treeview.enable_model_drag_dest([('text/plain', 0, 0)], \ gtk.gdk.ACTION_COPY) # Connect callbacks to VolumeMonitor self.mounts = gio.VolumeMonitor() self.mounts.connect('mount-added', self.on_mount_added) self.mounts.connect('mount-removed', self.on_mount_removed) # Initialize objects self.ok_cancel_dialog = Dialogs(DialogTypes.OK_CANCEL) self.bookmarks = BookMarks() self.icons = Icons(gtk.icon_theme_get_default()) # Initialize places home = os.environ['HOME'] desktop = os.path.expanduser("~/Desktop") self.places = [home, desktop] # Initialize variables self._cur_dir = desktop self._old_dir = " " self._filters = {} self._filter = '' self._files = [] self._show_hidden = False self._hidden_exts = ['.desktop'] self._copy = True self._selection = None self.nav_btn_list = [] self.nav_btn_path_dict = {} # Initialize self._init_nav_buttons()
def __init__(self, parent=None): super(MainMenuBar, self).__init__(parent) self.mainWindow = parent # parent should be a MainWindow self.docks = [] # sub-menus self.openRecMenu = \ widgets.MenuRecentFiles(self, self.mainWindow.recent_files_manager) # must load icons here Icons.load() # Actions -- # file actions self.newAct = QtWidgets.QAction(Icons.new, "&New", self) self.newAct.setShortcut('Ctrl+N') self.openAct = QtWidgets.QAction(Icons.openFile, "&Open", self) self.openAct.setShortcut('Ctrl+O') self.openRecAct = QtWidgets.QAction("Open &Recent", self) self.openRecAct.setMenu(self.openRecMenu) self.saveAct = QtWidgets.QAction(Icons.save, "&Save", self) self.saveAct.setShortcut('Ctrl+S') self.saveAsAct = QtWidgets.QAction(Icons.saveAs, "Save &As...", self) self.saveAsAct.setShortcut('Ctrl+Shift+S') self.saveAllAct = QtWidgets.QAction(Icons.saveAll, "Save A&ll", self) self.saveAllAct.setShortcut('Ctrl+Shift+A') self.closeAllAct = QtWidgets.QAction("Close All", self) self.exitAct = QtWidgets.QAction("E&xit", self) self.exitAct.setShortcut('Alt+F4') # tool actions self.interpAct = QtWidgets.QAction("&Interpreter Config...", self) self.runConfigAct = QtWidgets.QAction(Icons.runConfig, "Run &Config...", self) self.runAct = QtWidgets.QAction(Icons.run, "&Run", self) self.runAct.setShortcut('F5') # Top-level menus self.fileMenu = QtWidgets.QMenu("&File", self) self.fileMenu.addAction(self.newAct) self.fileMenu.addAction(self.openAct) self.fileMenu.addAction(self.openRecAct) self.fileMenu.addAction(self.closeAllAct) self.fileMenu.addSeparator() self.fileMenu.addAction(self.saveAct) self.fileMenu.addAction(self.saveAsAct) self.fileMenu.addAction(self.saveAllAct) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAct) self.addAction(self.fileMenu.menuAction()) # add to menubar self.editMenu = \ QtWidgets.QMenu("&Edit", self) # edit menu updated dynamically # self.editMenu.addActions(self.mainWindow.editor.actions()) self.addAction(self.editMenu.menuAction()) self.toolsMenu = QtWidgets.QMenu("&Tools", self) self.toolsMenu.addAction(self.interpAct) self.toolsMenu.addAction(self.runConfigAct) self.toolsMenu.addAction(self.runAct) self.toolsMenu.addSeparator() self.addAction(self.toolsMenu.menuAction()) self.viewMenu = QtWidgets.QMenu("&View", self) self.addAction(self.viewMenu.menuAction()) self.helpMenu = QtWidgets.QMenu("&Help", self) self.addAction(self.helpMenu.menuAction())
def build_menu_bar(self): get_icon = Icons().get_icon ######## Actions ## Save saveAction = QAction(QIcon(get_icon("document-save-as")), "&Save", self) saveAction.setShortcut("Ctrl+S") saveAction.setStatusTip("Save file") saveAction.triggered.connect(self.save_file) ## Save As saveAsAction = QAction(QIcon(get_icon("document-save")), "&Save As", self) saveAsAction.setStatusTip("Save file as...") saveAsAction.triggered.connect(self.save_file_as) ## Open openAction = QAction(QIcon(get_icon("document-open")), "&Open", self) openAction.setShortcut("Ctrl+O") openAction.setStatusTip("Open file") openAction.triggered.connect(self.open_file) ## Import template importAction = QAction(QIcon(get_icon("document-open")), "&Import template", self) importAction.setStatusTip("Import a template file") importAction.triggered.connect(self.import_template) ## Export exportAction = QAction(QIcon(get_icon("document-save")), "&Export PDF", self) exportAction.setShortcut("Ctrl+E") exportAction.setStatusTip("Export each character's profile as a PDF") exportAction.triggered.connect(self.export_file) if not canExportPDF: exportAction.setDisabled(True) ## Exit exitAction = QAction(QIcon(get_icon("application-exit")), "&Exit", self) exitAction.setShortcut("Ctrl+Q") exitAction.setStatusTip("Exit the application") exitAction.triggered.connect(qApp.quit) ## About action aboutAction = QAction(QIcon(get_icon("help-about")), "&About", self) aboutAction.setStatusTip("Information about the program") aboutAction.triggered.connect(self.about) ## Create the menubar menuBar = self.menuBar() ## Create file menu fileMenu = menuBar.addMenu("&File") fileMenu.addAction(openAction) ## Recents menu self.recentsMenu = fileMenu.addMenu("Recent") fileMenu.addSeparator() fileMenu.addAction(saveAction) fileMenu.addAction(saveAsAction) fileMenu.addSeparator() fileMenu.addAction(exportAction) fileMenu.addSeparator() fileMenu.addAction(exitAction) ## Create edit menu editMenu = menuBar.addMenu("&Edit") editMenu.addAction(importAction) helpMenu = menuBar.addMenu("&Help") helpMenu.addAction(aboutAction) self.load_recents_menu()
from flask import Flask from flask import Response from sense_hat import SenseHat from icons import Icons import json app = Flask(__name__) sense = SenseHat() icons = Icons() # My sense is upside down for reasons of cable. sense.set_rotation(180) @app.route('/temperator', methods=['GET']) def temperature(): r = {'temperature': sense.get_temperature()} return Response(json.dumps(r), mimetype='application/json') @app.route('/humidity', methods=['GET']) def humidity(): r = {'humidity': sense.get_humidity()} return Response(json.dumps(r), mimetype='application/json') @app.route('/pressure', methods=['GET']) def humidity(): r = {'pressure': sense.get_pressure()} return Response(json.dumps(r), mimetype='application/json') @app.route('/emotion' methods=['POST']) def emotion():
class ProjectTreeView(gtk.TreeView): """A widget for displaying the files within a repositoy.""" def __init__(self): """Constructor. Creates the initial view of the project repository.""" super(ProjectTreeView, self).__init__() self.__current_repository = None self.__activate_file = None self.__refresh = None self.__settings = Settings() self.__initialize_treeview() self.__initialize_icons() self.__initialize_columns() def set_activate_file(self, afile=None): """Sets the method to use when activating a file.""" if afile is not None and not callable(afile): raise ValueError, err0010 self.__activate_file = afile def set_refresh(self, refresh=None): """Sets the method to use when refreshing.""" if refresh is not None and not callable(refresh): raise ValueError, err0011 self.__refresh = refresh def get_repository(self): """Gets the URI associated with the currently opened repository.""" return self.__current_repository def refresh(self): """Refreshes the current view.""" current_repo = self.get_repository() # Check to be sure we have a current repository if current_repo is not None: # Collection to hold all expanded rows open_paths = [] # Append all the expanded paths to the collection self.map_expanded_rows(self.__map_expanded_rows, open_paths) self.__refresh() # Expand all previously expanded paths path_iter = self.get_model().get_iter_root() self.__expand_previously_open_rows(path_iter, open_paths) del open_paths[0:] self.queue_draw() def set_repository(self, uri): """Sets the repository to be viewed. @param uri: The URI to set the repository to. @type uri: a gnomevfs.URI """ self.__current_repository = uri self.get_model().clear() # Create the root directory within the list parent_dir = self.__append_descriptor(uri, True, None) # Be sure there is a loading item within the current directory self.__append_loading_cell(parent_dir) # Expand the current directory to show the rest of the files iterpath = self.get_model().get_path(parent_dir) self.expand_row(iterpath, False) self.queue_draw() def __expand_previously_open_rows(self, path_iter, open_paths): """Expands any previously opened paths after a refresh.""" while path_iter is not None: desc = self.get_model().get_value(path_iter, 0) # Be sure we have a PathDescriptor if isinstance(desc, PathDescriptor): # If the path was previously opened open it if desc.get_uri() in open_paths: path = self.get_model().get_path(path_iter) self.expand_row(path, False) # Remove it from the list open_paths.remove(desc.get_uri()) # If the iterator has children, check to see if any should # be open if self.get_model().iter_has_child(path_iter): child = self.get_model().iter_nth_child(path_iter, 0) self.__expand_previously_open_rows(child, open_paths) # Move to the next row path_iter = self.get_model().iter_next(path_iter) def __map_expanded_rows(self, widget, path, data): """Store previously opened paths.""" # Append URI values to track what is open path_iter = self.get_model().get_iter(path) if path_iter is not None: desc = self.get_model().get_value(path_iter, 0) if isinstance(desc, PathDescriptor): data.append(desc.get_uri()) def __initialize_treeview(self): """Create the view and set its properties.""" treestore = gtk.TreeStore(object, gtk.gdk.Pixbuf, gtk.gdk.Pixbuf) self.set_property(u'model', treestore) self.set_property(u'enable-search', False) self.set_property(u'headers-visible', False) self.connect(u'test-expand-row', self.__on_expand_row) self.connect(u'row-activated', self.__on_row_activated) self.connect(u'row-collapsed', self.__on_collapse_row) def __initialize_columns(self): """Creates the columns for the view.""" # Create the necessary widgets for the view image_renderer = gtk.CellRendererPixbuf() name_renderer = gtk.CellRendererText() column = gtk.TreeViewColumn() # Pach the icon renderer and the text label renderer into the view column.pack_start(image_renderer, False) column.pack_start(name_renderer, True) # Set the icons for the icon renderer column.set_attributes(image_renderer, pixbuf=1, pixbuf_expander_open=2, pixbuf_expander_closed=1) # Set the texit labels method for retrieving the file's name column.set_cell_data_func(name_renderer, self.__retrieve_filename) self.append_column(column) def __initialize_icons(self): """Retrieves the icons needed to display within the file view.""" self.__icons = Icons(self) def __populate_directory(self, uri, parent=None): """Populates the directory list alphabetically by directory then by file. @param uri: the URI of the directory. @type uri: a gnomevfs.URI @param parent: the parent iterator to append the child to. @type parent: a gtk.TreeIter """ # Retrieve directories alphabetically directory = gnomevfs.DirectoryHandle(uri) file_filter = self.__settings.get_file_filter() show_file = None if len(file_filter) > 0: comp = re.compile(file_filter) def __show_file(file_name): if comp.search(file_name) is not None: return True return False show_file = __show_file for file_info in sorted(directory, cmp=self.__compare_files): # Process folders if files.is_visible_dir(file_info): file_uri = uri.append_file_name(file_info.name) cur_dir = self.__append_descriptor(file_uri, True, parent) self.__append_loading_cell(cur_dir) # Process Files elif files.is_visible_file(file_info): if show_file is not None and not show_file(file_info.name): continue file_uri = uri.append_file_name(file_info.name) self.__append_descriptor(file_uri, False, parent) def __compare_files(self, file_a, file_b): """Compares to files and determines which is first based on file type and file name.""" type_a = file_a.type type_b = file_b.type # Make folders the most important in the list if type_a == gnomevfs.FILE_TYPE_DIRECTORY: type_a = 0 else: type_a = 1 if type_b == gnomevfs.FILE_TYPE_DIRECTORY: type_b = 0 else: type_b = 1 type_comp = cmp(type_a, type_b) # If the files are the same type then compare names if type_comp == 0: return cmp(file_a.name, file_b.name) return type_comp def __empty_directory(self, iterator): """Removes all the items within a directory on the tree.""" model = self.get_model() # Remove each of the child nodes within the iterator while model.iter_has_child(iterator): child = model.iter_nth_child(iterator, 0) model.remove(child) def __append_descriptor(self, uri, is_dir, parent): """Creates a tree node with a path descriptor.""" open_icon = None default_icon = None # Retrieve a default and open icon if the URI is a folder, otherwise # just a default icon if is_dir: open_icon = self.__icons.folder_open default_icon = self.__icons.folder else: default_icon = self.__icons.retrieve_file_icon(str(uri)) # Create a descriptor and append a new node that represents that # descriptor into the tree desc = PathDescriptor(uri, is_dir) parent_dir = self.get_model().append(parent, [desc, default_icon, open_icon]) # Attach the corresponding tree iterator to the descriptor desc.set_iter(parent_dir) return parent_dir def __append_empty_cell(self, iterator): """Creates an 'empty' cell within the tree.""" self.get_model().append(iterator, [msg0003, None, None]) def __append_loading_cell(self, iterator): """Creates a 'loading' cell within the tree.""" self.get_model().append(iterator, [msg0002, None, None]) def __retrieve_filename(self, column, cell, model, iterator): """Retrieves the filename of the PathDescriptor.""" desc = model.get_value(iterator, 0) # Retrieve the filename of the PathDescriptor or string. if isinstance(desc, PathDescriptor): cell.set_property(u'text', desc.get_name()) else: cell.set_property(u'text', desc) def __on_expand_row(self, widget, iterator, path, data=None): """Empties a directory then loads in the files.""" if iterator is not None: desc = self.get_model().get_value(iterator, 0) if not isinstance(desc, PathDescriptor): return # If the object is a directory clear its contents within the tree # and rescan it if desc.is_dir(): self.freeze_child_notify() # Empty the directory self.__empty_directory(iterator) self.__populate_directory(desc.get_uri(), iterator) # Append an "Empty" cell if the directory is empty if not self.get_model().iter_has_child(iterator): self.__append_empty_cell(iterator) self.thaw_child_notify() self.queue_draw() def __on_collapse_row(self, widget, iterator, path, data=None): """Empties a directory to conserve memory.""" if iterator is not None: desc = self.get_model().get_value(iterator, 0) if not isinstance(desc, PathDescriptor): return # If the object is a directory clear its contents within the tree # and rescan it if desc.is_dir(): self.freeze_child_notify() # Empty the directory self.__empty_directory(iterator) # Append a loading node to be used later when expanding self.__append_loading_cell(iterator) self.thaw_child_notify() self.queue_draw() def __on_row_activated(self, widget, path, view_column, data=None): """Enters a directory or loads a file.""" iterator = self.get_model().get_iter(path) if iterator is not None: desc = self.get_model().get_value(iterator, 0) # Be sure we hane a PathDescriptor before we try to activate the # node. if not isinstance(desc, PathDescriptor): return # Expand or collapse a directory if desc.is_dir(): if self.row_expanded(path): self.collapse_row(path) else: self.expand_row(path, False) # Activate the file else: if self.__activate_file is not None: self.__activate_file(desc) self.queue_draw()
class Collection(): # These values represent the root menu items. It is important, because # the queries may be different, depending on the values. These values # also appear in the URL-s (part of the server API) as is. COLLECTIONTYPE_PLACE_OF_USAGE_ID = "0" COLLECTIONTYPE_USER_GROUPS_ID = "1" COLLECTIONTYPE_AREA_OF_USAGE_ID = "2" IconDB = Icons() def executeRawQuery( self, objects, queryString, include=[], summaryMenu=[], converters={} ): data = [] result = objects.raw(queryString) for p in result: subset = [] if summaryMenu: subset.extend(summaryMenu) subset.append(["new_section"]) for column_name in include: s1 = unicode(column_name, errors='replace') s2 = getattr(p, column_name) if type(s2) is str: s2 = s2.decode("windows-1250") elif type(s2) is decimal.Decimal: s2 = str(s2) if column_name in converters.keys(): s2 = converters[column_name](str(s2).strip()) subset.append([s1, "", s2]) data.append(subset) return { "desc": self.desc, "data": data } def getAttr(self, p, field): attr = getattr(p, field) return attr if attr else 0 def generateTemperatureString(self, tableId, temperatureField): return '%s."%s"' % (tableId, temperatureField) def generateParentString(self, node): parentStr = "" for i in range(0, 9): parentStr += '("parent%d"=%s) or ' % (i, node) return parentStr def getActualField(self, set, attrName): for line in set: if line[0] == attrName: return line[2] def removeField(self, set, attrName): for line in set: if line[0] == attrName: set.remove(line) continue def draw(self, axisDesc, results, title_id, ylimit=None): dateAxis = [] # In the database, dt_num is a Delphi/float representation of the dates, starting point is 1899.12.30 0:0:0. Python datetime calculates with starting point 1.1.1 0:0:0. This magic number is teh fload difference of the two. delphiStartDate = datetime.date(1899, 12, 30) dataAxises = [[]] + list(repeat([], len(axisDesc))) if not len(list(results)): return { "desc": self.desc, "data": [] } for p in results: date = datetime.timedelta(self.getAttr(p, "dt_num")) + delphiStartDate dateAxis.append(date) for i in range(0, len(axisDesc)): dataAxises[i].append(self.getAttr(p, axisDesc[i]["column"])) dataAxises[i] fig = plt.figure() for i in range(0, len(axisDesc)): plt.plot_date(dateAxis, dataAxises[i], axisDesc[i]["line"], label=axisDesc[i]["label"], fillstyle='full') if ylimit: ax = plt.subplot(111) ax.set_ylim(ylimit) plt.legend() # Tweak spacing to prevent clipping of ylabel fig.autofmt_xdate() output = StringIO.StringIO() plt.savefig(output, format='png', orientation='landscape') im_data = output.getvalue() data = [["", base64.b64encode(im_data)]] return { "desc": self.desc, "data": [data] } def getLabels(self, column, language, isMetric="1"): columnTranslated = column if language == "hu": if column == "ua_l": columnTranslated = "készlet, " + ("liter " if isMetric == "1" else "gallon") elif column == "ua_l15": columnTranslated = "készlet, " + ("liter, 15˚C" if isMetric == "1" else "gallon, 58˚F") elif column == "hofok": columnTranslated = "höfok, " + ("˚C" if isMetric == "1" else "˚F") elif column == "h2o_mm": columnTranslated = "víz magasság, mm" elif column == "szazalek": columnTranslated = "százalék" elif column == "hiba": columnTranslated = "hibaszám" if language == "en": if column == "ua_l": columnTranslated = "inventory, " + ("liter " if isMetric == "1" else "gallon") elif column == "ua_l15": columnTranslated = "inventory, " + ("liter, 15˚C" if isMetric == "1" else "gallon, 58˚F") elif column == "hofok": columnTranslated = "temperature, " + ("˚C" if isMetric == "1" else "˚F") elif column == "h2o_mm": columnTranslated = "water level, mm" elif column == "szazalek": columnTranslated = "percentage" elif column == "hiba": columnTranslated = "error number" return columnTranslated def parseDbGrid(self, grid): p = re.compile('FieldName..(\w*)') return p.findall(grid) def getParent(self, node): return TreenodeModel.objects.get(dbindx=node).parent0 def getFieldsFromDBGrid(self, node, username, tabId): try: obj = Dbgrid.objects.get(user=username, node=node, ful_n=tabId) except Dbgrid.DoesNotExist: parent = self.getParent(node) if parent: return self.getFieldsFromDBGrid(parent.dbindx, username, tabId) else: return { "order_by": "", "fields": [] } fields = self.parseDbGrid(obj.grid) return { "order_by": obj.sorrend, "fields": fields } @staticmethod def FuelTypeConverter(t): if t == "1": return "E95" elif t == "2": return "Diesel" elif t == "3": return "Jet" return t
def build_menu_bar(self): get_icon = Icons().get_icon ## Is this a system install? sysInstall = (os.path.expanduser('~') in sys.argv[0]) ######## Actions ## Save saveAction = QAction( QIcon(get_icon("document-save-symbolic", sysInstall)), "&Save Settings", self) saveAction.setShortcut("Ctrl+S") saveAction.setStatusTip("Save current settings") saveAction.triggered.connect(self.save_settings) ## Import playlist importAction = QAction( QIcon(get_icon("document-open-symbolic", sysInstall)), "&Import URLs", self) importAction.setShortcut("Ctrl+I") importAction.setStatusTip("Import a saved list of URLs") importAction.triggered.connect(self.import_urls) ## Export playlist exportAction = QAction( QIcon(get_icon("document-save-symbolic", sysInstall)), "&Export URLs", self) exportAction.setShortcut("Ctrl+E") exportAction.setStatusTip("Export URLs to a text file") exportAction.triggered.connect(self.export_urls) ## Exit exitAction = QAction( QIcon(get_icon("application-exit-symbolic", sysInstall)), "&Exit", self) exitAction.setShortcut("Ctrl+Q") exitAction.setStatusTip("Exit the application") exitAction.triggered.connect(qApp.quit) ## Go goAction = QAction(QIcon(get_icon("go-next-symbolic", sysInstall)), "Download URLs", self) goAction.setShortcut("Return") goAction.setStatusTip("Download current URL list") goAction.triggered.connect(self.mainWidget.start_download) ## Paste pasteAction = QAction( QIcon(get_icon("edit-paste-symbolic", sysInstall)), "&Paste", self) pasteAction.setShortcut("Ctrl+V") pasteAction.setStatusTip("Add URL from clipboard") pasteAction.triggered.connect(self.mainWidget.quick_add_item) ## Set destination setDestAction = QAction( QIcon(get_icon("document-open-symbolic", sysInstall)), "Set &Download directory", self) setDestAction.setShortcut("Ctrl+D") setDestAction.setStatusTip("Choose your download directory") setDestAction.triggered.connect(self.mainWidget.set_destination) ## Allow duplicates self.dupeAction = QAction("Allow duplicates", self) self.dupeAction.setStatusTip("Allow duplicate URLs in queue") self.dupeAction.setCheckable(True) if self.opts["duplicates"] == "true": self.dupeAction.setChecked(True) self.dupeAction.triggered.connect(self.check_dupe_box) ## New folder for playlists self.playlistFolderAction = QAction("New folder for playlists", self) self.playlistFolderAction.setStatusTip( "Create a new folder for every playlist downloaded") self.playlistFolderAction.setCheckable(True) if self.opts["playlistFolder"] == "true": self.playlistFolderAction.setChecked(True) self.playlistFolderAction.triggered.connect( self.check_playlist_dir_box) ## About action aboutAction = QAction( QIcon(get_icon("help-about-symbolic", sysInstall)), "&About", self) aboutAction.setStatusTip("Information about the program") aboutAction.triggered.connect(self.about) ## ====== Theme actions ## System default theme defaultThemeAction = QAction("Default", self) defaultThemeAction.setStatusTip("Set theme to system default") defaultThemeAction.triggered.connect(self.toggle_theme_default) ## Light theme lightThemeAction = QAction("Light theme", self) lightThemeAction.setStatusTip("Use a light theme") lightThemeAction.triggered.connect(self.toggle_theme_light) ## Dark theme darkThemeAction = QAction("Dark theme", self) darkThemeAction.setStatusTip("Use a dark theme") darkThemeAction.triggered.connect(self.toggle_theme_dark) ## Create the menubar menuBar = self.menuBar() ## Create file menu fileMenu = menuBar.addMenu("&File") fileMenu.addAction(saveAction) fileMenu.addAction(exportAction) fileMenu.addSeparator() fileMenu.addAction(importAction) fileMenu.addSeparator() fileMenu.addAction(goAction) fileMenu.addSeparator() fileMenu.addAction(exitAction) ## Edit Menu editMenu = menuBar.addMenu("&Edit") editMenu.addAction(pasteAction) ## Settins Menu settingsMenu = menuBar.addMenu("&Settings") themesMenu = settingsMenu.addMenu("Theme") settingsMenu.addSeparator() settingsMenu.addAction(setDestAction) settingsMenu.addSeparator() settingsMenu.addAction(self.dupeAction) settingsMenu.addAction(self.playlistFolderAction) ## Themes submenu themesMenu.addAction(defaultThemeAction) themesMenu.addAction(lightThemeAction) themesMenu.addAction(darkThemeAction) ## Help menu helpMenu = menuBar.addMenu("&Help") helpMenu.addAction(aboutAction)
def init_UI(self): ## Just to make life easier get_icon = Icons().get_icon ## Start all of the widgets self.listWidget = ListWidget(self) ## The Destination button self.destButton = QPushButton(QIcon(get_icon("folder-open")), "") self.destButton.setToolTip("Choose download directory") ## Destination path edit self.destEdit = QLineEdit(self.parent.opts["downloadPath"]) self.destEdit.setToolTip("Path to destination directory") ## The profiles self.profileBox = QComboBox(self) self.init_profile_box() ## The other buttons self.addButton = QPushButton(QIcon(get_icon("list-add")), "") self.addButton.setToolTip("Add a URL manually") self.removeButton = QPushButton(QIcon(get_icon("list-remove")), "") self.removeButton.setToolTip("Remove selected URL") self.quickAddButton = QPushButton(QIcon(get_icon("edit-paste")), "") self.quickAddButton.setToolTip("Add a URL directly from the clipboard") self.goButton = QPushButton(QIcon(get_icon("go-next")), "") self.goButton.setToolTip("Download the list of URLs") ## The current progress bar self.currentProgressBar = QProgressBar(self) self.currentProgressBar.setTextVisible(False) ## The total progress bar self.totalProgressBar = QProgressBar(self) self.totalProgressBar.setTextVisible(False) ## The free space label self.freeLabel = QLabel(self) self.update_free_label() ## Connect it up self.connect_all() ## The destination layout dest = QHBoxLayout() dest.addWidget(self.destButton) dest.addWidget(self.destEdit, 1) ## Dest + profiles dBox = QVBoxLayout() dBox.addLayout(dest, 1) dBox.addWidget(self.profileBox) ## Free space fBox = QHBoxLayout() fBox.addWidget(QWidget(), 1) fBox.addWidget(self.freeLabel) ## Buttons layout hbox = QHBoxLayout() hbox.addWidget(QWidget(), 1) hbox.addWidget(self.addButton) hbox.addWidget(self.quickAddButton) hbox.addWidget(self.removeButton) hbox.addWidget(self.goButton) ## List label listLabel = QHBoxLayout() listLabel.addWidget(QLabel("URLs:")) ## List lBox = QVBoxLayout() lBox.addLayout(listLabel) lBox.addWidget(self.listWidget, 1) ## Lay 'em down by the fi-yah vbox = QVBoxLayout() vbox.addLayout(dBox) vbox.addLayout(lBox) vbox.addLayout(hbox) ## Progress bars #currentProgress = QHBoxLayout() #currentProgress.addWidget( QLabel( "Current" )) #currentProgress.addWidget( self.currentProgressBar ) #vbox.addLayout( currentProgress ) #totalProgress = QHBoxLayout() #totalProgress.addWidget( QLabel( "Total" )) #totalProgress.addWidget( self.totalProgressBar ) #vbox.addLayout( totalProgress ) vbox.addWidget(QLabel("Current")) vbox.addWidget(self.currentProgressBar) vbox.addWidget(QLabel("Total")) vbox.addWidget(self.totalProgressBar) vbox.addLayout(fBox) ## Set the layout self.setLayout(vbox)
def __initialize_icons(self): """Retrieves the icons needed to display within the file view.""" self.__icons = Icons(self)