added mvc skeleton
authorEugene Gagarin <mosfet07@ya.ru>
Fri, 20 Mar 2009 14:57:06 +0000 (17:57 +0300)
committerEugene Gagarin <mosfet07@ya.ru>
Fri, 20 Mar 2009 14:57:06 +0000 (17:57 +0300)
12 files changed:
src/findit_var1.py [new file with mode: 0755]
src/findit_var2.py [new file with mode: 0755]
src/mvc/controllers/__init__.py [new file with mode: 0755]
src/mvc/controllers/about.py [new file with mode: 0755]
src/mvc/controllers/application.py [new file with mode: 0755]
src/mvc/main.py [new file with mode: 0755]
src/mvc/models/__init__.py [new file with mode: 0755]
src/mvc/models/about.py [new file with mode: 0755]
src/mvc/models/application.py [new file with mode: 0755]
src/mvc/views/__init__.py [new file with mode: 0755]
src/mvc/views/about.py [new file with mode: 0755]
src/mvc/views/application.py [new file with mode: 0755]

diff --git a/src/findit_var1.py b/src/findit_var1.py
new file mode 100755 (executable)
index 0000000..e21bd48
--- /dev/null
@@ -0,0 +1,424 @@
+#!/usr/bin/env python
+# -*-coding: utf-8 -*-
+# vim: sw=4 ts=4 expandtab ai
+# pylint: disable-msg=C0301
+
+"""findIT: Gui prorgram to find various information.
+   At the moment it only finds largest files
+"""
+
+import gtk
+import gobject
+import pango
+from os import walk
+from os.path import join, abspath, normcase, basename, \
+                    isdir, getsize, getatime, getmtime, expanduser
+from heapq import nlargest
+import gettext
+import time
+from sys import platform
+
+try: 
+    import hildon
+    HILDON = True
+except ImportError:
+    HILDON = False
+
+try:
+    # Подразумевается, что ru/LC_MESSAGES/program.mo находится в текущем каталоге (sys.path[0])
+    # Для стандартного /usr/share/locale писать gettext.translation('findit')
+    #langRU = gettext.translation('findit', sys.path[0], languages=['ru'])
+    LANGRU = gettext.translation('findit')
+    LANGRU.install()
+except IOError:
+    # Закомментировать перед использованием pygettext
+    def _(text): 
+        return text
+
+
+### Common functions ###########################################################
+
+# Функция которая возвращает строку из числа и единиц для столбца "Размер"("Size")
+def size_convert(size):
+    """Return string with file size in b or Kb or Mb or Gb or Tb."""
+    for i, unit in enumerate(['%d b', '%.1f Kb', '%.2f Mb', '%.3f Gb', '%.4f Tb']):
+        if size < 1024**(i+1):
+            return unit % (size/1024.**i)
+    return '>1024 Tb'
+
+# Функция поставляющая размер файла и путь к нему
+def filegetter(startdir, obj):
+    """Generator of file sizes and paths based on os.walk."""
+    # Список игнорируемых каталогов:
+    ignore_dirs = ['/dev', '/proc', '/sys', '/mnt']
+    # Проходим по всем папкам вглубь от заданного пути
+    for dirpath, dirnames, fnames in walk(startdir):
+    # Исключаем каталоги из поиска в соответствии со списком исключений
+        for ign_dir in ignore_dirs[:]:
+            for dirname in dirnames[:]:
+                if ign_dir == normcase(join(abspath(dirpath), dirname)):
+                    dirnames.remove(dirname)
+                    ignore_dirs.remove(ign_dir)
+
+        for fname in fnames:
+            flpath = abspath(join(dirpath, fname))
+            # Выводим текущий опрашиваемый файл в строку статуса
+            obj.currfilelbl.set_text(flpath)
+            # обновляем окно
+            gtk.main_iteration()
+            # Останавливаем цикл по нажатию кнопки стоп
+            if obj.stopit:
+                obj.stopit = False
+                raise StopIteration
+            # Проверяем можем ли мы определить размер файла - иначе пропускаем его
+            try:
+                # Возвращаем размер и полный путь файла
+                yield getsize(flpath), flpath
+            except OSError:
+                continue
+
+# Fullscreen
+def toggle_fullscreen(obj):
+    """Switch fullscreen on/off."""
+    if obj.fullscreen:
+        obj.window.unfullscreen()
+    else: 
+        obj.window.fullscreen()
+    obj.fullscreen = not obj.fullscreen
+
+# Нажатие на кнопку клавиатуры
+def on_key_press(obj, event):
+    """Key press callback."""
+    # Toggle fullscreen on Maemo when hw key is pressed
+    if HILDON and event.keyval == gtk.keysyms.F6:
+        toggle_fullscreen(obj)
+
+
+### Properties dialog ##########################################################
+
+class PropertiesDialog(gtk.Dialog):
+    """File property dialog window."""
+
+    def __init__(self, app, path, size, bytesize):
+        """Create&show file properties dialog."""
+        gtk.Dialog.__init__(self, _('File properties'), app,
+            buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK))
+        self.set_wmclass('PropertiesDialog', 'FindIT')
+        self.set_resizable(False)
+
+        # Достаем свойства выбранного файла
+        name = basename(path)
+        access = time.strftime('%x %X', time.localtime(getatime(path)))
+        modified = time.strftime('%x %X', time.localtime(getmtime(path)))
+
+        # Таблица надписей
+        table = gtk.Table()
+        table.set_border_width(10)
+        table.set_col_spacings(10)
+        table.set_row_spacings(10)
+
+        # Надписи (подпись: значение)
+        lbls = [(gtk.Label(_(name)), gtk.Label(value)) for name, value in 
+            [('Name', name), ('Size', '%s (%d b)' % (size, bytesize)),
+             ('Opened', access), ('Modified', modified)]]
+
+        # Упаковка надписей в таблицу и выравнивание
+        for i, lbl in enumerate(lbls):
+            name, value = lbl
+            table.attach(name, 0, 1, i, i+1)
+            table.attach(value, 1, 2, i, i+1)
+            name.set_alignment(1, 0.5)
+            value.set_alignment(0, 0.5)
+
+        # Упаковка таблицы в vbox диалога
+        self.vbox.add(table)
+        self.show_all()
+        self.run()
+        self.destroy()
+
+
+### About dialog ###############################################################
+
+class AboutDialog(gtk.AboutDialog):
+    """About dialog window."""
+
+    def __init__(self, *args):
+        """Create&show about dialog."""
+        gtk.AboutDialog.__init__(self)
+        self.set_wmclass('AboutDialog', 'FindIT')
+
+        self.set_authors([ 'Alex Taker\n   * Email: alteker@gmail.com\n',
+                           'Eugene Gagarin\n   * Email: mosfet07@ya.ru\n',
+                           'Alexandr Popov\n   * Email: popov2al@gmail.com' ])
+        
+        self.set_comments('Tool for find some information on computer.')
+        self.set_version('0.1.0')
+        self.set_license("This program is free software; you can redistribute it and/or\nmodify it under the terms of the GNU General Public License\nas published by the Free Software Foundation; either version 3\nof the License, or (at your option) any later version.")
+        self.set_copyright('')
+        self.set_website('')
+
+        self.show_all()
+        self.run()
+        self.destroy()
+
+### Main window ################################################################
+
+class MainWindow(gtk.Window):
+    """Main window class."""
+
+    # Окно сообщения заданного типа с заданным текстом
+    def mess_window(self, mestype, content):
+        """Show popup message window."""
+        dialog = gtk.MessageDialog(parent=self, flags=gtk.DIALOG_MODAL,
+                                   type=mestype, buttons=gtk.BUTTONS_OK,
+                                   message_format=content)
+        dialog.set_wmclass('ErrorDialog', 'FindIT')
+        dialog.set_title( _('Error!') )
+        dialog.run()
+        dialog.destroy()
+
+    # Функция выполняющаяся при нажатии на кнопку "Показать"
+    def start_print(self, widget):
+        """Start file search. Button "Go" activate callback."""         
+#         self.start_path = self.srch_p_entr.get_text()
+        self.start_path = self.srch_p_btn.get_current_folder()
+        # Проверяем правильное ли значение введено
+        if isdir(self.start_path):
+            self.butt_start.set_sensitive(False)
+            self.butt_stop.set_sensitive(True)
+            self.propertiesbtn.set_sensitive(False)
+            # Получаем значение количества файлов из SpinButton
+            self.fl_cnt = int( self.file_cnt.get_value() )
+            # Очищаем список
+            self.treestore.clear()
+            self.treeview.columns_autosize()
+            # Получаем нужное количество самых больших файлов
+            for fsize, fpath in nlargest(self.fl_cnt, filegetter(self.start_path, self)):
+                # Возвращаем значения в treeview в таком порядке - путь,
+                # размер в Мб строкой и размер в байтах
+                # self.treestore.append(None, [fpath.replace(self.start_path,'', 1),
+                #        size_convert(fsize), fsize])
+
+                # Выдает какую-то перманентную ошибку при присвоении значений treestore -
+                # кто увидит скажите - нужна статистика
+                try: 
+                    self.treestore.append(None, [fpath, size_convert(fsize), fsize])
+                except SystemError:
+#                    print 'error', fpath, size_convert(fsize), fsize
+                    self.mess_window('error','Error in %s' % fpath)
+            self.butt_start.set_sensitive(True)
+            self.butt_stop.set_sensitive(False)
+            self.propertiesbtn.set_sensitive(True)
+#             self.srch_p_entr.grab_focus()
+            self.srch_p_btn.grab_focus()
+        else:
+            # Иначе выводим окошко с ошибкой
+            self.mess_window('error', _('Invalid directory') )
+
+    # Функция выполняющаяся при нажатии на кнопку "Стоп"
+    def stop_print(self, widget):
+        """Stop search. "Stop" button clicked callback."""
+        self.stopit = True
+
+    # Функция выполняющаяся при нажатии на кнопку "Свойства файла"
+    def show_properties_dialog(self, *args):
+        """Show property dialog window."""
+        selection = self.treeview.get_selection()
+        (model, item) = selection.get_selected()
+        try:
+            path = model.get_value(item, 0)
+            size = model.get_value(item, 1)
+            bytesize = model.get_value(item, 2)
+        except (TypeError, ValueError):
+            self.mess_window('error', _('Please select file') )
+            return
+        PropertiesDialog(self, path, size, bytesize)
+
+    # Создание меню
+    def create_menu(self):
+        """ Create main menu """
+        menubar = gtk.MenuBar()
+
+        # File menu
+        fileitem = gtk.MenuItem( _('_File') )     # Файл
+        filemenu = gtk.Menu()
+        fileitem.set_submenu(filemenu)
+
+        open_menuitem = gtk.ImageMenuItem(gtk.STOCK_OPEN)
+        delete_menuitem = gtk.ImageMenuItem(gtk.STOCK_DELETE)
+        properties_menuitem = gtk.ImageMenuItem(gtk.STOCK_PROPERTIES)
+        quit_menuitem = gtk.ImageMenuItem(gtk.STOCK_QUIT)
+        filemenu.add(open_menuitem)
+        filemenu.add(delete_menuitem)
+        filemenu.add(properties_menuitem)
+        filemenu.add(quit_menuitem)
+        properties_menuitem.connect('activate', self.show_properties_dialog)
+        quit_menuitem.connect('activate', gtk.main_quit)
+
+        # View menu
+        viewitem = gtk.MenuItem( _('_View') )    # Вид
+        viewmenu = gtk.Menu()
+
+        # Help menu
+        helpitem = gtk.MenuItem( _('_Help') )    # Помощь
+        helpmenu = gtk.Menu()
+        helpitem.set_submenu(helpmenu)
+
+        about_menuitem = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
+        helpmenu.add(about_menuitem)
+        about_menuitem.connect('activate', AboutDialog)
+
+        # Packing
+        menubar.add(fileitem)
+        menubar.add(viewitem)
+        menubar.add(helpitem)
+
+        return menubar
+
+#     def create_hildon_menu(self):
+#         """ Create Hildon main menu """
+
+    ### Window initialization ##################################################
+
+    def __init__(self, win_width, win_height, st_path):
+        """Create MainWindow."""
+        # Создаем новое окно
+        gtk.Window.__init__(self)
+        self.set_default_size(win_width, win_height)
+        self.set_border_width(4)
+        self.fullscreen = False
+        self.connect('delete_event', gtk.main_quit)
+        self.connect('key-press-event', on_key_press)
+        self.set_wmclass('MainWindow', 'FindIT')
+
+        #########  Добавляем элементы ################
+        # 1. Строка ввода каталога с которого начинать поиск
+
+        # 2. Кнопка "Обзор"
+        self.srch_p_btn = gtk.FileChooserButton( _('Browse...') )
+        self.srch_p_btn.set_action('select-folder')
+
+        # 3. Надпись1 "Количество отображаемых файлов:"
+        label1 = gtk.Label( _('Files quantity') )
+
+        # 4. Окошко ввода количества файлов, мин значение=1 макс=65536 по умолчанию 10
+        #    данные храняться в переменной self.fl_cnt
+        self.fl_cnt = 10
+        if HILDON:
+            self.file_cnt = hildon.NumberEditor(1, 99)
+            self.file_cnt.set_value(self.fl_cnt)
+        else:
+            adj = gtk.Adjustment(self.fl_cnt, 1, 65536, 1, 5, 0)
+            self.file_cnt = gtk.SpinButton(adj, 0, 0)
+
+        # 5.1 Кнопка "Показать"
+        self.butt_start = gtk.Button( _('Go') )
+        self.butt_start.connect('released', self.start_print)
+
+        # 5.2 Кнопка "Остановить"
+        self.butt_stop = gtk.Button( _('Stop') )
+        self.butt_stop.set_sensitive(False)
+        self.butt_stop.connect('clicked', self.stop_print)
+        self.stopit = False
+
+        # 5.3 Кнопка "Свойства файла"
+        self.propertiesbtn = gtk.Button( _('File properties') )
+        self.propertiesbtn.connect('clicked', self.show_properties_dialog)
+        self.propertiesbtn.set_sensitive(False)
+
+        # 6. Закладки
+
+        # 6.1 Список файлов
+        scrollwind = gtk.ScrolledWindow()
+        scrollwind.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+        # Определяем переменную в которой будет храниться выводимый список
+        self.treestore = gtk.TreeStore(str, str, int)
+        self.treeview = gtk.TreeView(self.treestore)
+        # На таблетке не отображаються заголовки столбцов по умолчанию -
+        # след строка заставляет их отображаться принудительно
+        self.treeview.set_headers_visible(1)
+        self.treeview.connect('row-activated', self.show_properties_dialog)
+
+        self.treestore.append(None, ['', '', 0])
+
+        # Создаем и настраиваем колонку с размером файла
+        size_col = gtk.TreeViewColumn( _('Size') )
+        cell = gtk.CellRendererText()
+        cell.set_property('width', 90)
+        size_col.pack_start(cell, True)
+        size_col.add_attribute(cell, 'text', 1)
+        self.treeview.append_column(size_col)
+        # Создаем и настраиваем колонку с именем файла
+        path_col = gtk.TreeViewColumn( _('Path') )
+        cell2 = gtk.CellRendererText()
+        path_col.pack_start(cell2, True)
+        path_col.add_attribute(cell2, 'text', 0)
+        self.treeview.append_column(path_col)
+
+        # Добавляем сортировку для колонок
+        self.treeview.set_search_column(1)
+        path_col.set_sort_column_id(0)
+        size_col.set_sort_column_id(2)
+
+        # 6.2 Надпись "Найти"
+
+        # 6.3 Строка выводящая текущий осматриваемый файл
+        self.currfilelbl = gtk.Label()
+        self.currfilelbl.set_alignment(0, 0.5)
+        self.currfilelbl.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
+        self.currfilelbl.set_padding(2, 2)
+        currfilefrm = gtk.Frame()
+        currfilefrm.add(self.currfilelbl)
+
+        # 7 Меню
+        if HILDON:
+            main_menu = self.create_hildon_menu()
+        else:
+            main_menu = self.create_menu()
+
+        #########  Упаковываем элементы ################
+        # Создаем основной вертикальный контейнер
+        main_vbox = gtk.VBox(False, 4)
+
+        # Создаем вспомогательный горизонтальный контейнер для Надписи1,
+        # окошка ввода количества файлов и кнопки "Показать"
+        hbox1 = gtk.HBox(False, 5)
+        # Добавляем вышеперечисленные элементы во вспомогат. контейнер
+        hbox1.pack_start(label1, False, False, 5)
+        hbox1.pack_start(self.file_cnt, False, False, 0)
+        hbox1.pack_start(self.butt_start, True, True, 0)
+        hbox1.pack_start(self.butt_stop, True, True, 0)
+        hbox1.pack_start(self.propertiesbtn, True, True, 0)
+
+        # Добавляем элементы в основной контейнер
+        main_vbox.pack_start(main_menu, False, False, 0)
+#         main_vbox.pack_start(self.srch_p_entr, False, False, 0)
+        main_vbox.pack_start(self.srch_p_btn, False, False, 0)
+        main_vbox.pack_start(hbox1, False, False, 0)
+        scrollwind.add(self.treeview)
+        main_vbox.pack_start(scrollwind, True, True, 0)
+        main_vbox.pack_start(currfilefrm, False, False, 0)
+
+        self.add(main_vbox)
+
+    def run(self):
+        """Show all widgets and run gtk.main()."""
+        self.show_all()
+        gtk.main()
+
+
+### Main call ##################################################################
+def main():
+    """Main function."""
+    gobject.set_application_name( _('FindIT') )
+
+    if platform == 'win32':
+        startpath = 'c:\\'
+    else:
+        startpath = expanduser('~')
+
+    MainWindow(575, 345, startpath).run()
+
+if __name__ == '__main__':
+    main()
diff --git a/src/findit_var2.py b/src/findit_var2.py
new file mode 100755 (executable)
index 0000000..e5151ca
--- /dev/null
@@ -0,0 +1,453 @@
+#!/usr/bin/env python
+# -*-coding: utf-8 -*-
+# vim: sw=4 ts=4 expandtab ai
+# pylint: disable-msg=C0301
+
+"""findIT: Gui prorgram to find various information.
+   At the moment it only finds largest files
+"""
+
+import gtk
+import gobject
+import pango
+from os import walk
+from os.path import join, abspath, normcase, basename, \
+                    isdir, getsize, getatime, getmtime, expanduser
+from heapq import nlargest
+import gettext
+import time
+from sys import platform
+
+try: 
+    import hildon
+    HILDON = True
+except ImportError:
+    HILDON = False
+
+try:
+    # Подразумевается, что ru/LC_MESSAGES/program.mo находится в текущем каталоге (sys.path[0])
+    # Для стандартного /usr/share/locale писать gettext.translation('findit')
+    #langRU = gettext.translation('findit', sys.path[0], languages=['ru'])
+    LANGRU = gettext.translation('findit')
+    LANGRU.install()
+except IOError:
+    # Закомментировать перед использованием pygettext
+    def _(text): 
+        return text
+
+
+### Common functions ###########################################################
+
+# Функция которая возвращает строку из числа и единиц для столбца "Размер"("Size")
+def size_convert(size):
+    """Return string with file size in b or Kb or Mb or Gb or Tb."""
+    for i, unit in enumerate(['%d b', '%.1f Kb', '%.2f Mb', '%.3f Gb', '%.4f Tb']):
+        if size < 1024**(i+1):
+            return unit % (size/1024.**i)
+    return '>1024 Tb'
+
+# Функция поставляющая размер файла и путь к нему
+def filegetter(startdir, obj):
+    """Generator of file sizes and paths based on os.walk."""
+    # Список игнорируемых каталогов:
+    ignore_dirs = ['/dev', '/proc', '/sys', '/mnt']
+    # Проходим по всем папкам вглубь от заданного пути
+    for dirpath, dirnames, fnames in walk(startdir):
+    # Исключаем каталоги из поиска в соответствии со списком исключений
+        for ign_dir in ignore_dirs[:]:
+            for dirname in dirnames[:]:
+                if ign_dir == normcase(join(abspath(dirpath), dirname)):
+                    dirnames.remove(dirname)
+                    ignore_dirs.remove(ign_dir)
+
+        for fname in fnames:
+            flpath = abspath(join(dirpath, fname))
+            # Выводим текущий опрашиваемый файл в строку статуса
+            obj.currfilelbl.set_text(flpath)
+            # обновляем окно
+            gtk.main_iteration()
+            # Останавливаем цикл по нажатию кнопки стоп
+            if obj.stopit:
+                obj.stopit = False
+                raise StopIteration
+            # Проверяем можем ли мы определить размер файла - иначе пропускаем его
+            try:
+                # Возвращаем размер и полный путь файла
+                yield getsize(flpath), flpath
+            except OSError:
+                continue
+
+# Fullscreen
+def toggle_fullscreen(obj):
+    """Switch fullscreen on/off."""
+    if obj.fullscreen:
+        obj.window.unfullscreen()
+    else: 
+        obj.window.fullscreen()
+    obj.fullscreen = not obj.fullscreen
+
+# Нажатие на кнопку клавиатуры
+def on_key_press(obj, event):
+    """Key press callback."""
+    # Toggle fullscreen on Maemo when hw key is pressed
+    if HILDON and event.keyval == gtk.keysyms.F6:
+        toggle_fullscreen(obj)
+
+
+### Properties dialog ##########################################################
+
+class PropertiesDialog(gtk.Dialog):
+    """File property dialog window."""
+
+    def __init__(self, app, path, size, bytesize):
+        """Create&show file properties dialog."""
+        gtk.Dialog.__init__(self, _('File properties'), app,
+            buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK))
+        self.set_wmclass('PropertiesDialog', 'FindIT')
+        self.set_resizable(False)
+
+        # Достаем свойства выбранного файла
+        name = basename(path)
+        access = time.strftime('%x %X', time.localtime(getatime(path)))
+        modified = time.strftime('%x %X', time.localtime(getmtime(path)))
+
+        # Таблица надписей
+        table = gtk.Table()
+        table.set_border_width(10)
+        table.set_col_spacings(10)
+        table.set_row_spacings(10)
+
+        # Надписи (подпись: значение)
+        lbls = [(gtk.Label(_(name)), gtk.Label(value)) for name, value in 
+            [('Name', name), ('Size', '%s (%d b)' % (size, bytesize)),
+             ('Opened', access), ('Modified', modified)]]
+
+        # Упаковка надписей в таблицу и выравнивание
+        for i, lbl in enumerate(lbls):
+            name, value = lbl
+            table.attach(name, 0, 1, i, i+1)
+            table.attach(value, 1, 2, i, i+1)
+            name.set_alignment(1, 0.5)
+            value.set_alignment(0, 0.5)
+
+        # Упаковка таблицы в vbox диалога
+        self.vbox.add(table)
+        self.show_all()
+        self.run()
+        self.destroy()
+
+
+### About dialog ###############################################################
+
+class AboutDialog(gtk.AboutDialog):
+    """About dialog window."""
+
+    def __init__(self, *args):
+        """Create&show about dialog."""
+        gtk.AboutDialog.__init__(self)
+        self.set_wmclass('AboutDialog', 'FindIT')
+
+        self.set_authors([     'Alex Taker\n   * Email: alteker@gmail.com\n',
+                           'Eugene Gagarin\n   * Email: mosfet07@ya.ru\n',
+                           'Alexandr Popov\n   * Email: popov2al@gmail.com' ])
+        
+        self.set_comments('Tool for find some information on computer.')
+        self.set_version('0.1.0')
+        self.set_license("This program is free software; you can redistribute it and/or\nmodify it under the terms of the GNU General Public License\nas published by the Free Software Foundation; either version 3\nof the License, or (at your option) any later version.")
+        self.set_copyright('')
+        self.set_website('')
+
+        self.show_all()
+        self.run()
+        self.destroy()
+
+### Main window ################################################################
+
+class MainWindow(gtk.Window):
+    """Main window class."""
+
+    # Окно сообщения заданного типа с заданным текстом
+    def mess_window(self, mestype, content):
+        """Show popup message window."""
+        dialog = gtk.MessageDialog(parent=self, flags=gtk.DIALOG_MODAL,
+                                   type=mestype, buttons=gtk.BUTTONS_OK,
+                                   message_format=content)
+        dialog.set_wmclass('ErrorDialog', 'FindIT')
+        dialog.set_title( _('Error!') )
+        dialog.run()
+        dialog.destroy()
+
+    # Функция выполняющаяся при нажатии на кнопку "Показать"
+    def start_print(self, widget):
+        """Start file search. Button "Go" activate callback."""         
+        self.start_path = self.srch_p_entr.get_text()
+        # Проверяем правильное ли значение введено
+        if isdir(self.start_path):
+            self.butt_start.set_sensitive(False)
+            self.butt_stop.set_sensitive(True)
+            self.propertiesbtn.set_sensitive(False)
+            # Получаем значение количества файлов из SpinButton
+            self.fl_cnt = int( self.file_cnt.get_value() )
+            # Очищаем список
+            self.treestore.clear()
+            self.treeview.columns_autosize()
+            # Получаем нужное количество самых больших файлов
+            for fsize, fpath in nlargest(self.fl_cnt, filegetter(self.start_path, self)):
+                # Возвращаем значения в treeview в таком порядке - путь,
+                # размер в Мб строкой и размер в байтах
+                # self.treestore.append(None, [fpath.replace(self.start_path,'', 1),
+                #        size_convert(fsize), fsize])
+
+                # Выдает какую-то перманентную ошибку при присвоении значений treestore -
+                # кто увидит скажите - нужна статистика
+                try: 
+                    self.treestore.append(None, [fpath, size_convert(fsize), fsize])
+                except SystemError:
+#                    print 'error', fpath, size_convert(fsize), fsize
+                    self.mess_window('error','Error in %s' % fpath)
+            self.butt_start.set_sensitive(True)
+            self.butt_stop.set_sensitive(False)
+            self.propertiesbtn.set_sensitive(True)
+#             self.srch_p_entr.grab_focus()
+            self.srch_p_btn.grab_focus()
+        else:
+            # Иначе выводим окошко с ошибкой
+            self.mess_window('error', _('Invalid directory') )
+
+    # Функция выполняющаяся при нажатии на кнопку "Стоп"
+    def stop_print(self, widget):
+        """Stop search. "Stop" button clicked callback."""
+        self.stopit = True
+
+    # Функция выполняющаяся при нажатии на кнопку "Обзор"
+    def browse(self, widget):
+        """Open directory browser. "Browse" button clicked callback."""
+        dialog = gtk.FileChooserDialog( title=_('Choose directory'),
+                                        parent=self,
+                                        action='select-folder',
+                                        buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK,
+                                                 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) )
+        dialog.set_current_folder(self.srch_p_entr.get_text())
+        dialog.show_all()
+        response = dialog.run()
+        if response == gtk.RESPONSE_OK:
+            self.srch_p_entr.set_text(dialog.get_filename())
+        dialog.destroy()
+            
+
+    # Функция выполняющаяся при нажатии на кнопку "Свойства файла"
+    def show_properties_dialog(self, *args):
+        """Show property dialog window."""
+        selection = self.treeview.get_selection()
+        (model, item) = selection.get_selected()
+        try:
+            path = model.get_value(item, 0)
+            size = model.get_value(item, 1)
+            bytesize = model.get_value(item, 2)
+        except (TypeError, ValueError):
+            self.mess_window('error', _('Please select file') )
+            return
+        PropertiesDialog(self, path, size, bytesize)
+
+    # Создание меню
+    def create_menu(self):
+        """ Create main menu """
+        menubar = gtk.MenuBar()
+
+        # File menu
+        fileitem = gtk.MenuItem( _('_File') )     # Файл
+        filemenu = gtk.Menu()
+        fileitem.set_submenu(filemenu)
+
+        open_menuitem = gtk.ImageMenuItem(gtk.STOCK_OPEN)
+        delete_menuitem = gtk.ImageMenuItem(gtk.STOCK_DELETE)
+        properties_menuitem = gtk.ImageMenuItem(gtk.STOCK_PROPERTIES)
+        quit_menuitem = gtk.ImageMenuItem(gtk.STOCK_QUIT)
+        filemenu.add(open_menuitem)
+        filemenu.add(delete_menuitem)
+        filemenu.add(properties_menuitem)
+        filemenu.add(quit_menuitem)
+        properties_menuitem.connect('activate', self.show_properties_dialog)
+        quit_menuitem.connect('activate', gtk.main_quit)
+
+        # View menu
+        viewitem = gtk.MenuItem( _('_View') )    # Вид
+        viewmenu = gtk.Menu()
+
+        # Help menu
+        helpitem = gtk.MenuItem( _('_Help') )    # Помощь
+        helpmenu = gtk.Menu()
+        helpitem.set_submenu(helpmenu)
+
+        about_menuitem = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
+        helpmenu.add(about_menuitem)
+        about_menuitem.connect('activate', AboutDialog)
+
+        # Packing
+        menubar.add(fileitem)
+        menubar.add(viewitem)
+        menubar.add(helpitem)
+
+        return menubar
+
+#     def create_hildon_menu(self):
+#         """ Create Hildon main menu """
+
+    ### Window initialization ##################################################
+
+    def __init__(self, win_width, win_height, st_path):
+        """Create MainWindow."""
+        # Создаем новое окно
+        gtk.Window.__init__(self)
+        self.set_default_size(win_width, win_height)
+        self.set_border_width(4)
+        self.fullscreen = False
+        self.connect('delete_event', gtk.main_quit)
+        self.connect('key-press-event', on_key_press)
+        self.set_wmclass('MainWindow', 'FindIT')
+
+        #########  Добавляем элементы ################
+        # 1. Строка ввода каталога с которого начинать поиск
+        #    переменная в которой храниться стартовый каталог = self.start_path
+        self.srch_p_entr = gtk.Entry()
+        self.start_path = st_path
+        self.srch_p_entr.set_text(self.start_path)
+        # Отключаем автокапитализацию(ввод первой буквы заглавной) на таблетке
+        if HILDON:
+            self.srch_p_entr.set_property('hildon-input-mode', 'full')
+        # Нажатие Enter в поле ввода
+        self.srch_p_entr.connect('activate', self.start_print)
+
+        # 2. Кнопка "Обзор"
+        self.srch_p_btn = gtk.Button('Browse...')
+        self.srch_p_btn.connect('clicked', self.browse)
+
+        # 3. Надпись1 "Количество отображаемых файлов:"
+        label1 = gtk.Label( _('Files quantity') )
+
+        # 4. Окошко ввода количества файлов, мин значение=1 макс=65536 по умолчанию 10
+        #    данные храняться в переменной self.fl_cnt
+        self.fl_cnt = 10
+        if HILDON:
+            self.file_cnt = hildon.NumberEditor(1, 99)
+            self.file_cnt.set_value(self.fl_cnt)
+        else:
+            adj = gtk.Adjustment(self.fl_cnt, 1, 65536, 1, 5, 0)
+            self.file_cnt = gtk.SpinButton(adj, 0, 0)
+
+        # 5.1 Кнопка "Показать"
+        self.butt_start = gtk.Button( _('Go') )
+        self.butt_start.connect('released', self.start_print)
+
+        # 5.2 Кнопка "Остановить"
+        self.butt_stop = gtk.Button( _('Stop') )
+        self.butt_stop.set_sensitive(False)
+        self.butt_stop.connect('clicked', self.stop_print)
+        self.stopit = False
+
+        # 5.3 Кнопка "Свойства файла"
+        self.propertiesbtn = gtk.Button( _('File properties') )
+        self.propertiesbtn.connect('clicked', self.show_properties_dialog)
+        self.propertiesbtn.set_sensitive(False)
+
+        # 6. Закладки
+
+        # 6.1 Список файлов
+        scrollwind = gtk.ScrolledWindow()
+        scrollwind.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+        # Определяем переменную в которой будет храниться выводимый список
+        self.treestore = gtk.TreeStore(str, str, int)
+        self.treeview = gtk.TreeView(self.treestore)
+        # На таблетке не отображаються заголовки столбцов по умолчанию -
+        # след строка заставляет их отображаться принудительно
+        self.treeview.set_headers_visible(1)
+        self.treeview.connect('row-activated', self.show_properties_dialog)
+
+        self.treestore.append(None, ['', '', 0])
+
+        # Создаем и настраиваем колонку с размером файла
+        size_col = gtk.TreeViewColumn( _('Size') )
+        cell = gtk.CellRendererText()
+        cell.set_property('width', 90)
+        size_col.pack_start(cell, True)
+        size_col.add_attribute(cell, 'text', 1)
+        self.treeview.append_column(size_col)
+        # Создаем и настраиваем колонку с именем файла
+        path_col = gtk.TreeViewColumn( _('Path') )
+        cell2 = gtk.CellRendererText()
+        path_col.pack_start(cell2, True)
+        path_col.add_attribute(cell2, 'text', 0)
+        self.treeview.append_column(path_col)
+
+        # Добавляем сортировку для колонок
+        self.treeview.set_search_column(1)
+        path_col.set_sort_column_id(0)
+        size_col.set_sort_column_id(2)
+
+        # 6.2 Надпись "Найти"
+
+        # 6.3 Строка выводящая текущий осматриваемый файл
+        self.currfilelbl = gtk.Label()
+        self.currfilelbl.set_alignment(0, 0.5)
+        self.currfilelbl.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
+        self.currfilelbl.set_padding(2, 2)
+        currfilefrm = gtk.Frame()
+        currfilefrm.add(self.currfilelbl)
+
+        # 7 Меню
+        if HILDON:
+            main_menu = self.create_hildon_menu()
+        else:
+            main_menu = self.create_menu()
+
+        #########  Упаковываем элементы ################
+        # Создаем основной вертикальный контейнер
+        main_vbox = gtk.VBox(False, 4)
+
+        # Создаем вспомогательный горизонтальный контейнер для Надписи1,
+        # окошка ввода количества файлов и кнопки "Показать"
+        hbox1 = gtk.HBox(False, 5)
+        # Добавляем вышеперечисленные элементы во вспомогат. контейнер
+        hbox1.pack_start(label1, False, False, 5)
+        hbox1.pack_start(self.file_cnt, False, False, 0)
+        hbox1.pack_start(self.butt_start, True, True, 0)
+        hbox1.pack_start(self.butt_stop, True, True, 0)
+        hbox1.pack_start(self.propertiesbtn, True, True, 0)
+
+        hbox2 = gtk.HBox(False, 5)
+        hbox2.pack_start(self.srch_p_entr, True, True, 0)
+        hbox2.pack_start(self.srch_p_btn, False, False, 0)
+
+        # Добавляем элементы в основной контейнер
+        main_vbox.pack_start(main_menu, False, False, 0)
+#         main_vbox.pack_start(self.srch_p_entr, False, False, 0)
+#         main_vbox.pack_start(self.srch_p_btn, False, False, 0)
+        main_vbox.pack_start(hbox2, False, False, 0)
+        main_vbox.pack_start(hbox1, False, False, 0)
+        scrollwind.add(self.treeview)
+        main_vbox.pack_start(scrollwind, True, True, 0)
+        main_vbox.pack_start(currfilefrm, False, False, 0)
+
+        self.add(main_vbox)
+
+    def run(self):
+        """Show all widgets and run gtk.main()."""
+        self.show_all()
+        gtk.main()
+
+
+### Main call ##################################################################
+def main():
+    """Main function."""
+    gobject.set_application_name( _('FindIT') )
+
+    if platform == 'win32':
+        startpath = 'c:\\'
+    else:
+        startpath = expanduser('~')
+
+    MainWindow(575, 345, startpath).run()
+
+if __name__ == '__main__':
+    main()
diff --git a/src/mvc/controllers/__init__.py b/src/mvc/controllers/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/src/mvc/controllers/about.py b/src/mvc/controllers/about.py
new file mode 100755 (executable)
index 0000000..8d2beec
--- /dev/null
@@ -0,0 +1,44 @@
+from gtkmvc import Controller
+import gtk
+import gobject
+
+class AboutCtrl(Controller):
+    """Controller of 'About' dialog. It handles the filling dialog and
+    the close button."""
+
+    def __init__(self, model):
+        Controller.__init__(self, model)
+        return
+
+    def register_view(self, view):
+        """Loads the text taking it from the model."""
+
+        Controller.register_view(self, view)
+        self.view.set_progname(self.model.progname)
+        self.view.set_version(self.model.version)
+#        self.view.set_authors(self.model.authors)
+        self.view.set_comments(self.model.comments)
+        self.view.set_license(self.model.license)
+        return
+
+    # -----------------------------------------------------
+    #                  user callbacks
+    # -----------------------------------------------------
+
+    # -----------------------------------------------------
+    #                    gtk signals
+    # -----------------------------------------------------
+    #def on_dialog_about_delete_event(self, win, event):
+    #    return True
+
+    #def on_button_close_clicked(self, button):
+    #    return
+
+    # -----------------------------------------------------
+    #                observable properties
+    # -----------------------------------------------------
+#     def property_credits_value_change(self, model, old, new):
+#         self.view.set_text(new)
+#         return
+
+    pass # end of class
diff --git a/src/mvc/controllers/application.py b/src/mvc/controllers/application.py
new file mode 100755 (executable)
index 0000000..c117b7b
--- /dev/null
@@ -0,0 +1,50 @@
+from gtkmvc import Controller
+import gtk
+
+from about import AboutCtrl
+from views.about import AboutView
+
+
+class ApplicationCtrl(Controller):
+    """Controller of the top-level window (application)"""
+
+    def __init__(self, model):
+        Controller.__init__(self, model)
+        return
+
+    def register_view(self, view):
+        """Creates treeview columns, and connect missing signals"""
+        Controller.register_view(self, view)
+
+        # connects the signals:
+        self.view['main_window'].connect('destroy', gtk.main_quit)
+        self.view['about_btn'].connect('clicked', self.on_tb_about_clicked)
+        self.view['quit_btn'].connect('clicked', self.on_tb_quit_clicked)
+        return
+
+    # -----------------------------------------------------
+    #                  user callbacks
+    # -----------------------------------------------------
+
+    def quit(self):
+        gtk.main_quit()
+        return
+
+    # -----------------------------------------------------
+    #                    gtk signals
+    # -----------------------------------------------------
+
+    def on_tb_about_clicked(self, tb):
+        c = AboutCtrl(self.model.about)
+        v = AboutView(c)
+        v.run() # this runs in modal mode
+        return
+
+    def on_tb_quit_clicked(self, bt):
+        self.quit()
+
+    # -----------------------------------------------------
+    #                observable properties
+    # -----------------------------------------------------
+
+    pass # end of class
diff --git a/src/mvc/main.py b/src/mvc/main.py
new file mode 100755 (executable)
index 0000000..8291541
--- /dev/null
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# -*-coding: utf-8 -*-
+# vim: sw=4 ts=4 expandtab ai
+# pylint: disable-msg=C0301
+
+
+__progname__ = 'FindIT'
+__version__ = '0.2.0'
+
+get_ui = 'console'
+
+def main():
+
+    from models.application import ApplicationModel as MyModel
+    from controllers.application import ApplicationCtrl as MyCtrl
+    from views.application import ApplicationView as MyView
+
+    import gtk
+
+    m = MyModel()
+    c = MyCtrl(m)
+    v = MyView(c)
+
+    gtk.main()
+    return
+
+if __name__ == "__main__":
+    main()
diff --git a/src/mvc/models/__init__.py b/src/mvc/models/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/src/mvc/models/about.py b/src/mvc/models/about.py
new file mode 100755 (executable)
index 0000000..8491feb
--- /dev/null
@@ -0,0 +1,35 @@
+from gtkmvc import Model
+
+from __main__ import __version__, __progname__
+
+
+class AboutModel(Model):
+
+    # Observable properties
+    __properties__ = {
+        'authors'  : '',
+        'comments' : '',
+        'license'  : '',
+        }
+
+    def __init__(self):
+        Model.__init__(self)
+
+        self.progname = __progname__
+        self.version = __version__
+
+        self.authors = [    'Alex Taker\n   * Email: alteker@gmail.com\n',
+                        'Eugene Gagarin\n   * Email: mosfet07@ya.ru\n',
+                        'Alexandr Popov\n   * Email: popov2al@gmail.com' ]
+
+        self.comments = 'Tool for find some information on computer.'
+
+        self.license = \
+'This program is free software; you can redistribute it and/or\nmodify it \
+under the terms of the GNU General Public License\nas published by the Free \
+Software Foundation; either version 3\nof the License, or (at your option) \
+any later version.'
+
+        return
+
+    pass # end of class
diff --git a/src/mvc/models/application.py b/src/mvc/models/application.py
new file mode 100755 (executable)
index 0000000..c841508
--- /dev/null
@@ -0,0 +1,15 @@
+from gtkmvc import Model
+import os.path
+
+from about import AboutModel
+
+
+class ApplicationModel(Model):
+
+    def __init__(self):
+        Model.__init__(self)
+
+        self.about = AboutModel()
+        return
+
+    pass # end of class
diff --git a/src/mvc/views/__init__.py b/src/mvc/views/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/src/mvc/views/about.py b/src/mvc/views/about.py
new file mode 100755 (executable)
index 0000000..ee77d78
--- /dev/null
@@ -0,0 +1,42 @@
+from gtkmvc import View
+import gtk
+
+
+class AboutView(View):
+    """This is the view for the 'About' dialog"""
+
+    def __init__(self, ctrl):
+        View.__init__(self, ctrl, register=False)
+
+        dialog = gtk.AboutDialog()
+        self['dialog_about'] = dialog
+        ctrl.register_view(self)
+
+        return
+
+    def set_progname(self, text):
+        self['dialog_about'].set_name(text)
+        return
+
+    def set_version(self, text):
+        self['dialog_about'].set_version(text)
+        return
+
+    def set_authors(self, text):
+        self['dialog_about'].set_authors(text)
+        return
+
+    def set_comments(self, text):
+        self['dialog_about'].set_comments(text)
+        return
+
+    def set_license(self, text):
+        self['dialog_about'].set_license(text)
+        return
+
+    def run(self):
+        res = self['dialog_about'].run()
+        self['dialog_about'].destroy()
+        return res
+
+    pass # end of class
diff --git a/src/mvc/views/application.py b/src/mvc/views/application.py
new file mode 100755 (executable)
index 0000000..78325e3
--- /dev/null
@@ -0,0 +1,36 @@
+from gtkmvc import View
+import os.path
+import gtk
+
+
+class ApplicationView(View):
+    """A view for the top level window (application)"""
+
+    def __init__(self, ctrl):
+        View.__init__(self, ctrl, register=False)
+
+        window = gtk.Window()
+        window.set_border_width(4)
+
+        hbox = gtk.HBox(4, True)
+
+        about_btn = gtk.Button('About')
+        quit_btn = gtk.Button('Exit')
+
+        about_btn.set_size_request(100, 150)
+        quit_btn.set_size_request(100, 150)
+
+        hbox.pack_start(about_btn, True, True, 0)
+        hbox.pack_start(quit_btn, True, True, 0)
+
+        window.add(hbox)
+        window.show_all()
+
+        self['main_window'] = window
+        self['about_btn'] = about_btn
+        self['quit_btn'] = quit_btn
+
+        ctrl.register_view(self)
+        return
+
+    pass # end of class