diff --git a/lector/__main__.py b/lector/__main__.py
index ad564b7..3f3d4d8 100755
--- a/lector/__main__.py
+++ b/lector/__main__.py
@@ -34,7 +34,7 @@ from PyQt5 import QtWidgets, QtGui, QtCore
from lector import database
from lector import sorter
from lector.toolbars import LibraryToolBar, BookToolBar
-from lector.widgets import Tab
+from lector.widgets import Tab, DragDropListView, DragDropTableView
from lector.delegates import LibraryDelegate
from lector.threaded import BackGroundTabUpdate, BackGroundBookAddition, BackGroundBookDeletion
from lector.library import Library
@@ -62,6 +62,13 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
# Initialize translation function
self._translate = QtCore.QCoreApplication.translate
+ # Create library widgets
+ self.listView = DragDropListView(self, self.listPage)
+ self.gridLayout_4.addWidget(self.listView, 0, 0, 1, 1)
+
+ self.tableView = DragDropTableView(self, self.tablePage)
+ self.gridLayout_3.addWidget(self.tableView, 0, 0, 1, 1)
+
# Empty variables that will be infested soon
self.settings = {}
self.thread = None # Background Thread
@@ -318,24 +325,104 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
my_args = cl_parser.positionalArguments()
if my_args:
file_list = [QtCore.QFileInfo(i).absoluteFilePath() for i in my_args]
- books = sorter.BookSorter(
- file_list,
- ('addition', 'manual'),
- self.database_path,
- self.settings['auto_tags'],
- self.temp_dir.path())
+ self.process_post_hoc_files(file_list, True)
- parsed_books = books.initiate_threads()
- if not parsed_books:
- return
+ def process_post_hoc_files(self, file_list, open_files_after_processing):
+ # Takes care of both dragged and dropped files
+ # As well as files sent as command line arguments
+ books = sorter.BookSorter(
+ file_list,
+ ('addition', 'manual'),
+ self.database_path,
+ self.settings['auto_tags'],
+ self.temp_dir.path())
- database.DatabaseFunctions(self.database_path).add_to_database(parsed_books)
- self.lib_ref.generate_model('addition', parsed_books, True)
+ parsed_books = books.initiate_threads()
+ if not parsed_books:
+ return
- file_dict = {QtCore.QFileInfo(i).absoluteFilePath(): None for i in my_args}
+ database.DatabaseFunctions(self.database_path).add_to_database(parsed_books)
+ self.lib_ref.generate_model('addition', parsed_books, True)
+
+ file_dict = {i: None for i in file_list}
+ if open_files_after_processing:
self.open_files(file_dict)
- self.move_on()
+ self.move_on()
+
+ def open_files(self, path_hash_dictionary):
+ # file_paths is expected to be a dictionary
+ # This allows for threading file opening
+ # Which should speed up multiple file opening
+ # especially @ application start
+
+ file_paths = [i for i in path_hash_dictionary]
+
+ for filename in path_hash_dictionary.items():
+
+ file_md5 = filename[1]
+ if not file_md5:
+ try:
+ with open(filename[0], 'rb') as current_book:
+ first_bytes = current_book.read(1024 * 32) # First 32KB of the file
+ file_md5 = hashlib.md5(first_bytes).hexdigest()
+ except FileNotFoundError:
+ return
+
+ # Remove any already open files
+ # Set focus to last file in case only one is open
+ for i in range(1, self.tabWidget.count()):
+ tab_metadata = self.tabWidget.widget(i).metadata
+ if tab_metadata['hash'] == file_md5:
+ file_paths.remove(filename[0])
+ if not file_paths:
+ self.tabWidget.setCurrentIndex(i)
+ return
+
+ if not file_paths:
+ return
+
+ def finishing_touches():
+ self.profile_functions.format_contentView()
+ self.start_culling_timer()
+
+ print('Attempting to open: ' + ', '.join(file_paths))
+
+ contents = sorter.BookSorter(
+ file_paths,
+ ('reading', None),
+ self.database_path,
+ True,
+ self.temp_dir.path()).initiate_threads()
+
+ # TODO
+ # Notification feedback in case all books return nothing
+
+ if not contents:
+ return
+
+ for i in contents:
+ # New tabs are created here
+ # Initial position adjustment is carried out by the tab itself
+ file_data = contents[i]
+ Tab(file_data, self)
+
+ if self.settings['last_open_tab'] == 'library':
+ self.tabWidget.setCurrentIndex(0)
+ self.listView.setFocus()
+ self.settings['last_open_tab'] = None
+ return
+
+ for i in range(1, self.tabWidget.count()):
+ this_path = self.tabWidget.widget(i).metadata['path']
+ if self.settings['last_open_tab'] == this_path:
+ self.tabWidget.setCurrentIndex(i)
+ self.settings['last_open_tab'] = None
+ finishing_touches()
+ return
+
+ self.tabWidget.setCurrentIndex(self.tabWidget.count() - 1)
+ finishing_touches()
def start_culling_timer(self):
if self.settings['perform_culling']:
@@ -626,80 +713,6 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
self.open_files(path)
- def open_files(self, path_hash_dictionary):
- # file_paths is expected to be a dictionary
- # This allows for threading file opening
- # Which should speed up multiple file opening
- # especially @ application start
-
- file_paths = [i for i in path_hash_dictionary]
-
- for filename in path_hash_dictionary.items():
-
- file_md5 = filename[1]
- if not file_md5:
- try:
- with open(filename[0], 'rb') as current_book:
- first_bytes = current_book.read(1024 * 32) # First 32KB of the file
- file_md5 = hashlib.md5(first_bytes).hexdigest()
- except FileNotFoundError:
- return
-
- # Remove any already open files
- # Set focus to last file in case only one is open
- for i in range(1, self.tabWidget.count()):
- tab_metadata = self.tabWidget.widget(i).metadata
- if tab_metadata['hash'] == file_md5:
- file_paths.remove(filename[0])
- if not file_paths:
- self.tabWidget.setCurrentIndex(i)
- return
-
- if not file_paths:
- return
-
- def finishing_touches():
- self.profile_functions.format_contentView()
- self.start_culling_timer()
-
- print('Attempting to open: ' + ', '.join(file_paths))
-
- contents = sorter.BookSorter(
- file_paths,
- ('reading', None),
- self.database_path,
- True,
- self.temp_dir.path()).initiate_threads()
-
- # TODO
- # Notification feedback in case all books return nothing
-
- if not contents:
- return
-
- for i in contents:
- # New tabs are created here
- # Initial position adjustment is carried out by the tab itself
- file_data = contents[i]
- Tab(file_data, self)
-
- if self.settings['last_open_tab'] == 'library':
- self.tabWidget.setCurrentIndex(0)
- self.listView.setFocus()
- self.settings['last_open_tab'] = None
- return
-
- for i in range(1, self.tabWidget.count()):
- this_path = self.tabWidget.widget(i).metadata['path']
- if self.settings['last_open_tab'] == this_path:
- self.tabWidget.setCurrentIndex(i)
- self.settings['last_open_tab'] = None
- finishing_touches()
- return
-
- self.tabWidget.setCurrentIndex(self.tabWidget.count() - 1)
- finishing_touches()
-
def statusbar_visibility(self):
if self.sender() == self.libraryToolBar.searchBar:
if self.libraryToolBar.searchBar.text() == '':
diff --git a/lector/resources/mainwindow.py b/lector/resources/mainwindow.py
index 6df390e..83d3a6a 100644
--- a/lector/resources/mainwindow.py
+++ b/lector/resources/mainwindow.py
@@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'raw/main.ui'
#
-# Created by: PyQt5 UI code generator 5.9.2
+# Created by: PyQt5 UI code generator 5.10.1
#
# WARNING! All changes made in this file will be lost!
@@ -35,20 +35,6 @@ class Ui_MainWindow(object):
self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
self.gridLayout_4.setSpacing(0)
self.gridLayout_4.setObjectName("gridLayout_4")
- self.listView = QtWidgets.QListView(self.listPage)
- self.listView.setFrameShape(QtWidgets.QFrame.NoFrame)
- self.listView.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
- self.listView.setProperty("showDropIndicator", False)
- self.listView.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
- self.listView.setMovement(QtWidgets.QListView.Static)
- self.listView.setProperty("isWrapping", True)
- self.listView.setResizeMode(QtWidgets.QListView.Fixed)
- self.listView.setLayoutMode(QtWidgets.QListView.SinglePass)
- self.listView.setViewMode(QtWidgets.QListView.IconMode)
- self.listView.setUniformItemSizes(True)
- self.listView.setWordWrap(True)
- self.listView.setObjectName("listView")
- self.gridLayout_4.addWidget(self.listView, 0, 0, 1, 1)
self.stackedWidget.addWidget(self.listPage)
self.tablePage = QtWidgets.QWidget()
self.tablePage.setObjectName("tablePage")
@@ -56,20 +42,6 @@ class Ui_MainWindow(object):
self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
self.gridLayout_3.setSpacing(0)
self.gridLayout_3.setObjectName("gridLayout_3")
- self.tableView = QtWidgets.QTableView(self.tablePage)
- self.tableView.setFrameShape(QtWidgets.QFrame.Box)
- self.tableView.setFrameShadow(QtWidgets.QFrame.Plain)
- self.tableView.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContentsOnFirstShow)
- self.tableView.setEditTriggers(QtWidgets.QAbstractItemView.DoubleClicked|QtWidgets.QAbstractItemView.EditKeyPressed|QtWidgets.QAbstractItemView.SelectedClicked)
- self.tableView.setAlternatingRowColors(True)
- self.tableView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
- self.tableView.setGridStyle(QtCore.Qt.NoPen)
- self.tableView.setSortingEnabled(True)
- self.tableView.setWordWrap(False)
- self.tableView.setObjectName("tableView")
- self.tableView.horizontalHeader().setVisible(True)
- self.tableView.verticalHeader().setVisible(False)
- self.gridLayout_3.addWidget(self.tableView, 0, 0, 1, 1)
self.stackedWidget.addWidget(self.tablePage)
self.gridLayout_2.addWidget(self.stackedWidget, 0, 0, 1, 1)
self.tabWidget.addTab(self.tab, "")
diff --git a/lector/resources/raw/main.ui b/lector/resources/raw/main.ui
index a284e88..137d8d4 100644
--- a/lector/resources/raw/main.ui
+++ b/lector/resources/raw/main.ui
@@ -55,46 +55,6 @@
0
- -
-
-
- QFrame::NoFrame
-
-
- QAbstractItemView::NoEditTriggers
-
-
- false
-
-
- QAbstractItemView::ExtendedSelection
-
-
- QListView::Static
-
-
- true
-
-
- QListView::Fixed
-
-
- QListView::SinglePass
-
-
- 0
-
-
- QListView::IconMode
-
-
- true
-
-
- true
-
-
-
@@ -114,43 +74,6 @@
0
- -
-
-
- QFrame::Box
-
-
- QFrame::Plain
-
-
- QAbstractScrollArea::AdjustToContentsOnFirstShow
-
-
- QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked
-
-
- true
-
-
- QAbstractItemView::SelectRows
-
-
- Qt::NoPen
-
-
- true
-
-
- false
-
-
- false
-
-
- false
-
-
-
diff --git a/lector/widgets.py b/lector/widgets.py
index e563606..51cd6eb 100644
--- a/lector/widgets.py
+++ b/lector/widgets.py
@@ -666,3 +666,81 @@ class PliantQGraphicsScene(QtWidgets.QGraphicsScene):
self.parent.load_cover(cover_pixmap, True)
self.parent.show()
+
+
+class DragDropListView(QtWidgets.QListView):
+ # This is the library listview
+ def __init__(self, main_window, parent):
+ super(DragDropListView, self).__init__(parent)
+ self.main_window = main_window
+ self.setAcceptDrops(True)
+ self.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)
+ self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
+ self.setResizeMode(QtWidgets.QListView.Fixed)
+ self.setLayoutMode(QtWidgets.QListView.SinglePass)
+ self.setViewMode(QtWidgets.QListView.IconMode)
+ self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
+ self.setProperty("showDropIndicator", False)
+ self.setProperty("isWrapping", True)
+ self.setFrameShape(QtWidgets.QFrame.NoFrame)
+ self.setUniformItemSizes(True)
+ self.setWordWrap(True)
+ self.setObjectName("listView")
+
+ def dragEnterEvent(self, event):
+ if event.mimeData().hasUrls():
+ event.acceptProposedAction()
+ else:
+ super(DragDropListView, self).dragEnterEvent(event)
+
+ def dragMoveEvent(self, event):
+ super(DragDropListView, self).dragMoveEvent(event)
+
+ def dropEvent(self, event):
+ if event.mimeData().hasUrls():
+ file_list = [url.path() for url in event.mimeData().urls()]
+ self.main_window.process_post_hoc_files(file_list, False)
+ event.acceptProposedAction()
+ else:
+ super(DragDropListView, self).dropEvent(event)
+
+
+class DragDropTableView(QtWidgets.QTableView):
+ # This is the library tableview
+ def __init__(self, main_window, parent):
+ super(DragDropTableView, self).__init__(parent)
+ self.main_window = main_window
+ self.setAcceptDrops(True)
+ self.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)
+ self.setFrameShape(QtWidgets.QFrame.Box)
+ self.setFrameShadow(QtWidgets.QFrame.Plain)
+ self.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContentsOnFirstShow)
+ self.setEditTriggers(
+ QtWidgets.QAbstractItemView.DoubleClicked |
+ QtWidgets.QAbstractItemView.EditKeyPressed |
+ QtWidgets.QAbstractItemView.SelectedClicked)
+ self.setAlternatingRowColors(True)
+ self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
+ self.setGridStyle(QtCore.Qt.NoPen)
+ self.setSortingEnabled(True)
+ self.setWordWrap(False)
+ self.setObjectName("tableView")
+ self.horizontalHeader().setVisible(True)
+ self.verticalHeader().setVisible(False)
+
+ def dragEnterEvent(self, event):
+ if event.mimeData().hasUrls():
+ event.acceptProposedAction()
+ else:
+ super(DragDropTableView, self).dragEnterEvent(event)
+
+ def dragMoveEvent(self, event):
+ super(DragDropTableView, self).dragMoveEvent(event)
+
+ def dropEvent(self, event):
+ if event.mimeData().hasUrls():
+ file_list = [url.path() for url in event.mimeData().urls()]
+ self.main_window.process_post_hoc_files(file_list, False)
+ event.acceptProposedAction()
+ else:
+ super(DragDropTableView, self).dropEvent(event)