1
0
mirror of https://github.com/gryf/pygtktalog.git synced 2025-12-17 19:40:21 +01:00

* Added statisics.

* Bug fix on files disapear in file view.
 * Code clean up.
This commit is contained in:
2008-04-08 13:25:13 +00:00
parent 344f4be232
commit a36ca62b73
7 changed files with 758 additions and 498 deletions

8
README
View File

@@ -60,13 +60,14 @@ For version 1.0 following aims have to be done:
- file details:
- files properties
x thumbnail
- description
- file information (date, size, etc) (50%)
x description
- exif information
- keywords (tags)
- gthumb integration
- adding images (60% done)
x generating/saving thumbnails
x moving hardcoded files extensions into config
x statistics
Legend: [-] not done, [x] done.
@@ -74,7 +75,6 @@ For version 2.0:
- Icon grid in files view
- command line support: query, adding media to collection etc
- internationalization support
- statistics
Removed:
- filetypes handling (movies, images, archives, documents etc). Now it have
@@ -92,7 +92,7 @@ Removed:
- anidb link/imdb link
Maybe in future versions. Now text file descriptions and tags have to be
enough for good and fast information search.
- file information (date, size, etc) (50%) (no need for?)
NOTES
=====

View File

@@ -259,12 +259,14 @@
<widget class="GtkCheckButton" id="ch_compress">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Compress collection</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>

View File

@@ -1,373 +1,398 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--*- mode: xml -*-->
<glade-interface>
<widget class="GtkDialog" id="inputDialog">
<property name="visible">True</property>
<property name="title" translatable="yes">Disk label - pyGTKtalog</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="has_separator">True</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="cancelbutton1">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-6</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="okbutton1">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="label">gtk-ok</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-5</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">Disk label</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">3</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="volname">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">True</property>
<signal name="activate" handler="on_volname_activate" last_modification_time="Sun, 26 Nov 2006 17:34:10 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkDialog" id="addDirDialog">
<property name="visible">True</property>
<property name="title" translatable="yes">dialog1</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="has_separator">True</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox2">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area2">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="cancelbutton2">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-6</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="okbutton2">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-ok</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-5</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="border_width">3</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkFrame" id="frame2">
<property name="border_width">3</property>
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0.5</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<child>
<widget class="GtkAlignment" id="alignment2">
<property name="border_width">3</property>
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">12</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="homogeneous">False</property>
<property name="row_spacing">3</property>
<property name="column_spacing">3</property>
<child>
<widget class="GtkEntry" id="dirvolname">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes">New</property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="directory">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="label" translatable="yes">Disk Label:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="label" translatable="yes">Select directory:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="browse">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Browse...</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_browse_clicked" last_modification_time="Sun, 03 Dec 2006 17:04:04 GMT"/>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Select directory and enter label&lt;/b&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkDialog" id="inputDialog">
<property name="visible">True</property>
<property name="title" translatable="yes">Disk label - pyGTKtalog</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="xpad">3</property>
<property name="label" translatable="yes">Disk label</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="volname">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="activates_default">True</property>
<signal name="activate" handler="on_volname_activate"/>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="position">2</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="cancelbutton1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">-6</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="okbutton1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="label">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">-5</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkDialog" id="addDirDialog">
<property name="visible">True</property>
<property name="title" translatable="yes">dialog1</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox2">
<property name="visible">True</property>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="border_width">3</property>
<child>
<widget class="GtkFrame" id="frame2">
<property name="visible">True</property>
<property name="border_width">3</property>
<property name="label_xalign">0</property>
<child>
<widget class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
<property name="border_width">3</property>
<property name="left_padding">12</property>
<child>
<widget class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="column_spacing">3</property>
<property name="row_spacing">3</property>
<child>
<placeholder/>
</child>
<child>
<widget class="GtkButton" id="browse">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Browse...</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_browse_clicked"/>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Select directory:</property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Disk Label:</property>
</widget>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="directory">
<property name="visible">True</property>
<property name="can_focus">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="dirvolname">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="text" translatable="yes">New</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Select directory and enter label&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
</child>
</widget>
<packing>
<property name="position">2</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area2">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="cancelbutton2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">-6</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="okbutton2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="label">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">-5</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkDialog" id="statDialog">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">pyGTKtalog - stats</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox3">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">2</property>
<child>
<widget class="GtkTable" id="table2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="n_rows">4</property>
<property name="n_columns">2</property>
<property name="column_spacing">2</property>
<child>
<widget class="GtkLabel" id="size_label">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Total size:</property>
<property name="justify">GTK_JUSTIFY_RIGHT</property>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="files_label">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Number of files:</property>
<property name="justify">GTK_JUSTIFY_RIGHT</property>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="dirs_label">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Number of directories:</property>
<property name="justify">GTK_JUSTIFY_RIGHT</property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="discs_label">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Number of discs:</property>
<property name="justify">GTK_JUSTIFY_RIGHT</property>
</widget>
<packing>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="size_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="editable">False</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="files_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="editable">False</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="dirs_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="editable">False</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="discs_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="editable">False</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area3">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="button1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">gtk-close</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@@ -141,6 +141,7 @@
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_find1_activate"/>
<accelerator key="f" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
@@ -171,7 +172,7 @@
<child>
<widget class="GtkMenuItem" id="add_cd">
<property name="visible">True</property>
<property name="label" translatable="yes">Add CD/DVD</property>
<property name="label" translatable="yes">Add _CD/DVD</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_add_cd_activate"/>
<accelerator key="a" modifiers="GDK_CONTROL_MASK" signal="activate"/>
@@ -180,9 +181,10 @@
<child>
<widget class="GtkMenuItem" id="add_directory1">
<property name="visible">True</property>
<property name="label" translatable="yes">Add Directory</property>
<property name="label" translatable="yes">Add _Directory</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_add_directory1_activate"/>
<accelerator key="d" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
@@ -190,6 +192,20 @@
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="stat1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Catalog _statistics</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_stat1_activate"/>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator6">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="cancel1">
<property name="visible">True</property>
@@ -566,6 +582,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="rules_hint">True</property>
<signal name="button_press_event" handler="on_files_button_press_event"/>
<signal name="row_activated" handler="on_files_row_activated"/>
<signal name="cursor_changed" handler="on_files_cursor_changed"/>
<signal name="key_release_event" handler="on_files_key_release_event"/>
@@ -877,6 +894,7 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">_Add tag</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_add_tag1_activate"/>
</widget>
</child>
<child>

View File

@@ -50,13 +50,13 @@ class MainController(Controller):
widgets = (
"discs","files",
'save1','save_as1','cut1','copy1','paste1','delete1','add_cd','add_directory1',
'tb_save','tb_addcd','tb_find','nb_dirs','description',
'tb_save','tb_addcd','tb_find','nb_dirs','description','stat1',
)
widgets_all = (
"discs","files",
'file1','edit1','add_cd','add_directory1','help1',
'tb_save','tb_addcd','tb_find','tb_new','tb_open','tb_quit',
'nb_dirs','description',
'nb_dirs','description','stat1',
)
widgets_cancel = ('cancel','cancel1')
@@ -146,22 +146,22 @@ class MainController(Controller):
self.__do_quit()
return True
def on_tb_quit_clicked(self,widget):
def on_tb_quit_clicked(self, widget):
self.__do_quit()
def on_quit1_activate(self,widget):
def on_quit1_activate(self, widget):
self.__do_quit()
def on_new1_activate(self,widget):
def on_new1_activate(self, widget):
self.__new_db()
def on_tb_new_clicked(self,widget):
def on_tb_new_clicked(self, widget):
self.__new_db()
def on_add_cd_activate(self,widget):
def on_add_cd_activate(self, widget):
self.__add_cd()
def on_tb_addcd_clicked(self,widget):
def on_tb_addcd_clicked(self, widget):
self.__add_cd()
def on_add_directory1_activate(self, widget):
@@ -169,7 +169,7 @@ class MainController(Controller):
self.__add_directory()
return
def on_about1_activate(self,widget):
def on_about1_activate(self, widget):
"""Show about dialog"""
Dialogs.Abt("pyGTKtalog", __version__, "About",
["Roman 'gryf' Dobosz"], licence)
@@ -207,6 +207,20 @@ class MainController(Controller):
def on_save_as1_activate(self, widget):
self.__save_as()
def on_stat1_activate(self, menu_item):
self.__show_stats()
def on_statistics1_activate(self, menu_item):
model = self.view['discs'].get_model()
try:
path, column = self.view['discs'].get_cursor()
selected_iter = self.model.discs_tree.get_iter(path)
except:
return
selected_id = self.model.discs_tree.get_value(selected_iter, 0)
self.__show_stats(selected_id)
def on_tb_open_clicked(self, widget):
self.__open()
@@ -242,7 +256,7 @@ class MainController(Controller):
return False
if event.button == 3:
"""show context menu"""
"""Right mouse button. Show context menu."""
try:
selection = treeview.get_selection()
model, list_of_paths = selection.get_selected_rows()
@@ -286,26 +300,44 @@ class MainController(Controller):
self.view['discs'].collapse_all()
return
def on_files_cursor_changed(self,treeview):
def on_files_button_press_event(self, tree, event):
try:
path, column, x, y = tree.get_path_at_pos(int(event.x),
int(event.y))
except TypeError:
tree.get_selection().unselect_all()
return False
if event.button == 3: # Right mouse button. Show context menu.
try:
selection = tree.get_selection()
model, list_of_paths = selection.get_selected_rows()
except TypeError:
list_of_paths = []
self.__popup_files_menu(event)
return True
def on_files_cursor_changed(self, treeview):
"""Show details of selected file"""
model, paths = treeview.get_selection().get_selected_rows()
#try:
itera = model.get_iter(paths[0])
if model.get_value(itera,4) == 1:
#directory, do nothin', just turn off view
'''self.view['details'].hide()
buf = self.view['details'].get_buffer()
buf.set_text('')
self.view['details'].set_buffer(buf)'''
else:
#file, show what you got.
#self.details.get_top_widget()
iter = model.get_iter(treeview.get_cursor()[0])
selected_item = self.model.files_list.get_value(iter, 0)
self.__get_item_info(selected_item)
#except:
# if __debug__:
# print "c_main.py: on_files_cursor_changed() insufficient iterator"
try:
itera = model.get_iter(paths[0])
if model.get_value(itera,4) == 1:
#directory, do nothin', just turn off view
'''self.view['details'].hide()
buf = self.view['details'].get_buffer()
buf.set_text('')
self.view['details'].set_buffer(buf)'''
else:
#file, show what you got.
#self.details.get_top_widget()
iter = model.get_iter(treeview.get_cursor()[0])
selected_item = self.model.files_list.get_value(iter, 0)
self.__get_item_info(selected_item)
except:
if __debug__:
print "c_main.py: on_files_cursor_changed() insufficient iterator"
return
def on_files_key_release_event(self, a, event):
@@ -376,6 +408,9 @@ class MainController(Controller):
self.__open(path)
return
def on_add_tag1_activate(self, menu_item):
print self.view['discs'].get_cursor()
def on_update1_activate(self, menu_item):
"""Update disc under cursor position"""
@@ -411,7 +446,7 @@ class MainController(Controller):
self.__set_title(filepath=self.model.filename, modified=True)
return
def on_debugbtn_clicked(self,widget):
def on_debugbtn_clicked(self, widget):
"""Debug. To remove in stable version, including button in GUI"""
if __debug__:
print "\nc_main.py: on_debugbtn_clicked()"
@@ -713,6 +748,12 @@ class MainController(Controller):
self.view['discs_popup'].show_all()
return
def __popup_files_menu(self, event):
self.view['files_popup'].popup(None, None, None, event.button,
event.time)
self.view['files_popup'].show_all()
return
def __generate_recent_menu(self):
self.recent_menu = gtk.Menu()
for i in self.model.config.recent:
@@ -786,4 +827,8 @@ class MainController(Controller):
buff.insert_with_tags(iter, cloud['name'], tag)
self.view['tag_cloud_textview'].set_buffer(buff)
def __show_stats(self, selected_id=None):
data = self.model.get_stats(selected_id)
label = Dialogs.StatsDialog(data).run()
pass # end of class

View File

@@ -327,7 +327,97 @@ class MainModel(ModelMT):
self.discs_tree.remove(branch_iter)
return
def get_stats(self, selected_id):
"""get statistic information"""
retval = {}
if selected_id:
sql = """select id, type, parent_id from files where id=?"""
self.db_cursor.execute(sql, (selected_id,))
res = self.db_cursor.fetchone()
if not res:
return retval
selected_item = {'id':res[0], 'type':res[1], 'parent': res[2]}
# collect all parent_id's
parents = []
def _recurse(fid):
parents.append(fid)
sql = """select id from files where type=? and parent_id=? and parent_id!=1"""
self.db_cursor.execute(sql, (self.DIR, fid))
res = self.db_cursor.fetchall()
if res:
for row in res:
_recurse(row[0])
_recurse(selected_id)
if selected_item['parent'] == 1:
parents.pop(0)
retval['discs'] = 1
retval['dirs'] = len(parents)
parents.append(selected_id)
files_count = 0
for p in parents:
sql = """select count(id) from files where type!=0 and type!=1 and parent_id=?"""
self.db_cursor.execute(sql, (p,))
res = self.db_cursor.fetchone()
if res:
files_count+=res[0]
retval['files'] = files_count
sql = """select size from files where id=?"""
self.db_cursor.execute(sql, (selected_id,))
res = self.db_cursor.fetchone()
if res:
retval['size'] = self.__bytes_to_human(res[0])
else:
sql = """select count(id) from files where parent_id=1 and type=1"""
self.db_cursor.execute(sql)
res = self.db_cursor.fetchone()
if res:
retval['discs'] = res[0]
sql = """select count(id) from files where parent_id!=1 and type=1"""
self.db_cursor.execute(sql)
res = self.db_cursor.fetchone()
if res:
retval['dirs'] = res[0]
sql = """select count(id) from files where parent_id!=1 and type!=1"""
self.db_cursor.execute(sql)
res = self.db_cursor.fetchone()
if res:
retval['files'] = res[0]
sql = """select sum(size) from files where parent_id=1 and type=1"""
self.db_cursor.execute(sql)
res = self.db_cursor.fetchone()
if res:
retval['size'] = self.__bytes_to_human(res[0])
return retval
# private class functions
def __bytes_to_human(self, integer):
if integer <= 0 or integer < 1024:
return "%d bytes" % integer
t = integer /1024.0
if t < 1 or t < 1024:
return "%d bytes (%d kB)" % (integer, t)
t = t /1024.0
if t < 1 or t < 1024:
return "%d bytes (%d MB)" % (integer, t)
t = t /1024.0
if t < 1 or t < 1024:
return "%d bytes (%d GB)" % (integer, t)
t = t /1024.0
return "%d bytes (%d TB)" % (integer, t)
def __clear_trees(self):
self.__clear_files_tree()
self.__clear_discs_tree()
@@ -396,23 +486,28 @@ class MainModel(ModelMT):
filename TEXT,
filepath TEXT,
date datetime,
size integer,
type integer,
source integer,
size_x integer,
size_y integer,
filetype integer,
size INTEGER,
type INTEGER,
source INTEGER,
note TEXT,
description TEXT);""")
self.db_cursor.execute("""create table
tags(id INTEGER PRIMARY KEY AUTOINCREMENT,
file_id INTEGER,
group_id INTEGER,
tag TEXT);""")
self.db_cursor.execute("""create table
tags_files(file_id INTEGER,
tag_id INTEGER);""")
self.db_cursor.execute("""create table
groups(id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
color TEXT);""")
self.db_cursor.execute("""create table
thumbnails(id INTEGER PRIMARY KEY AUTOINCREMENT,
file_id INTEGER,
filename TEXT);""")
self.db_cursor.execute("insert into files values(1, 1, 'root', null, \
0, 0, 0, 0, null, null, null, null);")
self.db_cursor.execute("insert into files values(1, 1, 'root', null, 0, 0, 0, 0, null, null, null, null);")
self.db_cursor.execute("insert into groups values(1, 'default', 'black');")
def __scan(self):
"""scan content of the given path"""
@@ -496,36 +591,32 @@ class MainModel(ModelMT):
#return -1
return 0
#############
# directories
for i in dirs:
if self.fsenc:
j = i.decode(self.fsenc)
else:
j = i
j = self.__decode_filename(i)
current_dir = os.path.join(root, i)
try:
st = os.stat(os.path.join(root,i))
st = os.stat(current_dir)
st_mtime = st.st_mtime
except OSError:
st_mtime = 0
# do NOT follow symbolic links
if os.path.islink(os.path.join(root,i)):
l = os.readlink(os.path.join(root,i))
if self.fsenc:
l = l.decode(self.fsenc)
else:
l = l
if os.path.islink(current_dir):
l = self.__decode_filename(os.readlink(current_dir))
sql = """
insert into files(parent_id, filename, filepath, date, size, type)
values(?,?,?,?,?,?)
"""
db_cursor.execute(sql, (currentid, j + " -> " + l,
os.path.join(path,i), st_mtime, 0,
ocurrent_dir, st_mtime, 0,
self.LIN))
dirsize = 0
else:
dirsize = __recurse(currentid, j, os.path.join(path,i),
dirsize = __recurse(currentid, j, current_dir,
st_mtime, 0, self.DIR, myit)
if dirsize == -1:
@@ -533,13 +624,17 @@ class MainModel(ModelMT):
else:
_size = _size + dirsize
########
# files:
for i in files:
if self.abort:
break
self.count = self.count + 1
current_path = os.path.join(root,i)
current_file = os.path.join(root, i)
try:
st = os.stat(current_path)
st = os.stat(current_file)
st_mtime = st.st_mtime
st_size = st.st_size
except OSError:
@@ -547,62 +642,70 @@ class MainModel(ModelMT):
st_size = 0
_size = _size + st_size
j = i
if self.fsenc:
j = i.decode(self.fsenc)
j = self.__decode_filename(i)
sql = """
insert into files(parent_id, filename, filepath, date, size, type)
values(?,?,?,?,?,?)
"""
db_cursor.execute(sql, (currentid, j, os.path.join(path,i),
st_mtime, st_size, self.FIL))
if self.count % 32 == 0:
update = True
# do NOT follow symbolic links
if os.path.islink(current_file):
l = self.__decode_filename(os.readlink(current_file))
sql = """insert into files(parent_id, filename, filepath,
date, size, type)
values(?,?,?,?,?,?)"""
db_cursor.execute(sql, (currentid, j + " -> " + l,
current_file, st_mtime, 0,
self.LIN))
else:
update = False
sql = """
insert into files(parent_id, filename, filepath, date, size, type)
values(?,?,?,?,?,?)
"""
db_cursor.execute(sql, (currentid, j, current_file,
st_mtime, st_size, self.FIL))
###########################
# fetch details about files
if self.config.confd['retrive']:
update = True
sql = """select seq FROM sqlite_sequence WHERE name='files'"""
db_cursor.execute(sql)
fileid = db_cursor.fetchone()[0]
if self.count % 32 == 0:
update = True
else:
update = False
ext = i.split('.')[-1].lower()
###########################
# fetch details about files
if self.config.confd['retrive']:
update = True
sql = """select seq FROM sqlite_sequence WHERE name='files'"""
db_cursor.execute(sql)
fileid = db_cursor.fetchone()[0]
# Images - thumbnails and exif data
if self.config.confd['thumbs'] and ext in self.IMG:
path, exif, ret_code = Thumbnail(current_path, base=self.internal_dirname).save(fileid)
if ret_code != -1:
sql = """insert into thumbnails(file_id, filename) values (?, ?)"""
db_cursor.execute(sql, (fileid,
path.split(self.internal_dirname)[1][1:]))
ext = i.split('.')[-1].lower()
if self.config.confd['exif']:
# TODO: exif implementation
pass
# Images - thumbnails and exif data
if self.config.confd['thumbs'] and ext in self.IMG:
path, exif, ret_code = Thumbnail(current_file, base=self.internal_dirname).save(fileid)
if ret_code != -1:
sql = """insert into thumbnails(file_id, filename) values (?, ?)"""
db_cursor.execute(sql, (fileid,
path.split(self.internal_dirname)[1][1:]))
# Extensions - user defined actions
if ext in self.config.confd['extensions'].keys():
cmd = self.config.confd['extensions'][ext]
arg = string.replace(current_path, '"', '\\"')
output = os.popen(cmd % arg).readlines()
desc = ''
for line in output:
desc += line
#desc = string.replace(desc, "\n", "\\n")
sql = """update files set description=? where id=?"""
db_cursor.execute(sql, (desc, fileid))
if self.config.confd['exif']:
# TODO: exif implementation
pass
#if i.split('.').[-1].lower() in mov_ext:
# # video only
# info = filetypeHelper.guess_video(os.path.join(root,i))
### end of scan
# Extensions - user defined actions
if ext in self.config.confd['extensions'].keys():
cmd = self.config.confd['extensions'][ext]
arg = string.replace(current_file, '"', '\\"')
output = os.popen(cmd % arg).readlines()
desc = ''
for line in output:
desc += line
#desc = string.replace(desc, "\n", "\\n")
sql = """update files set description=? where id=?"""
db_cursor.execute(sql, (desc, fileid))
#if i.split('.').[-1].lower() in mov_ext:
# # video only
# info = filetypeHelper.guess_video(os.path.join(root,i))
### end of scan
if update:
self.statusmsg = "Scannig: %s" % current_path
self.statusmsg = "Scannig: %s" % current_file
self.progress = step * self.count
sql = """update files set size=? where id=?"""
@@ -695,34 +798,53 @@ class MainModel(ModelMT):
return
def __remove_branch_form_db(self, root_id):
parent_ids = [root_id,]
sql = """select id from files where parent_id = ? and type = 1"""
self.db_cursor.execute(sql, (root_id,))
ids = self.db_cursor.fetchall()
"""Remove subtree from main tree, remove tags from database
remove all possible data, like thumbnails"""
fids = []
def get_children(fid):
parent_ids.append(fid)
sql = """select id from files where parent_id = ? and type = 1"""
fids.append(fid)
sql = """select id from files where parent_id = ?"""
self.db_cursor.execute(sql, (fid,))
res = self.db_cursor.fetchall()
for i in res:
get_children(i[0])
if len(res)>0:
for i in res:
get_children(i[0])
for i in ids:
get_children(i[0])
get_children(root_id)
def generator():
for c in parent_ids:
for c in fids:
yield (c,)
sql = """delete from files where type = 1 and parent_id = ?"""
self.db_cursor.executemany(sql, generator())
# remove files records
sql = """delete from files where id = ?"""
self.db_cursor.executemany(sql, generator())
# remove tags records
sql = """delete from tags_files where file_id = ?"""
self.db_cursor.executemany(sql, generator())
# remove thumbnails
arg =''
for c in fids:
if len(arg) > 0:
arg+=", %d" % c
else:
arg = "%d" % c
sql = """select filename from thumbnails where file_id in (%s)""" % arg
self.db_cursor.execute(sql)
res = self.db_cursor.fetchall()
if len(res) > 0:
for fn in res:
os.unlink(os.path.join(self.internal_dirname, fn[0]))
# remove thumbs records
sql = """delete from thumbnails where file_id = ?"""
self.db_cursor.executemany(sql, generator())
self.db_connection.commit()
return
def __append_added_volume(self):
"""append branch from DB to existing tree model"""
#connect
@@ -762,4 +884,10 @@ class MainModel(ModelMT):
db_connection.close()
return
def __decode_filename(self, txt):
if self.fsenc:
return txt.decode(self.fsenc)
else:
return txt
pass # end of class

View File

@@ -276,3 +276,45 @@ class LoadDBFile(object):
a = Err("Error - pyGTKtalog","File doesn't exist.","The file that you choose does not exist. Choose another one, or cancel operation.")
ch = True
res,filename = self.show_dialog()
class StatsDialog(object):
"""Sepcific dialog for display stats"""
def __init__(self, values={}):
self.gladefile = os.path.join(utils.globals.GLADE_DIR, "dialogs.glade")
self.values = values
def run(self):
gladexml = gtk.glade.XML(self.gladefile, "statDialog")
dialog = gladexml.get_widget("statDialog")
if self.values.has_key('discs'):
entry = gladexml.get_widget("discs_entry")
entry.set_text(str(self.values['discs']))
else:
label = gladexml.get_widget("discs_label")
entry = gladexml.get_widget("discs_entry")
label.hide()
entry.hide()
if self.values.has_key('dirs'):
entry = gladexml.get_widget("dirs_entry")
entry.set_text(str(self.values['dirs']))
else:
label = gladexml.get_widget("dirs_label")
entry = gladexml.get_widget("dirs_entry")
label.hide()
entry.hide()
if self.values.has_key('files'):
entry = gladexml.get_widget("files_entry")
entry.set_text(str(self.values['files']))
if self.values.has_key('size'):
entry = gladexml.get_widget("size_entry")
entry.set_text(str(self.values['size']))
result = dialog.run()
dialog.destroy()
if result == gtk.RESPONSE_OK:
return entry.get_text()
return None