File indexing completed on 2024-04-28 17:06:18
0001 /* 0002 SPDX-FileCopyrightText: 2000-2002 Shie Erlich <krusader@users.sourceforge.net> 0003 SPDX-FileCopyrightText: 2000-2002 Rafi Yanai <krusader@users.sourceforge.net> 0004 SPDX-FileCopyrightText: 2004-2022 Krusader Krew <https://krusader.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef KRVIEW_H 0010 #define KRVIEW_H 0011 0012 // QtCore 0013 #include <QHash> 0014 #include <QList> 0015 #include <QModelIndex> 0016 #include <QRegExp> 0017 #include <QTimer> 0018 #include <QVariant> 0019 // QtGui 0020 #include <QDropEvent> 0021 #include <QPixmap> 0022 #include <utility> 0023 0024 #include "krviewproperties.h" 0025 0026 class KrView; 0027 class KrViewItem; 0028 class KrPreviews; 0029 class KrViewInstance; 0030 class DirListerInterface; 0031 0032 typedef QList<KrViewItem *> KrViewItemList; 0033 0034 // operator can handle two ways of doing things: 0035 // 1. if the view is a widget (inherits krview and klistview for example) 0036 // 2. if the view HAS A widget (a krview-son has a member of klistview) 0037 // this is done by specifying the view and the widget in the constructor, 0038 // even if they are actually the same object (specify it twice in that case) 0039 class KrViewOperator : public QObject 0040 { 0041 Q_OBJECT 0042 public: 0043 KrViewOperator(KrView *view, QWidget *widget); 0044 ~KrViewOperator() override; 0045 0046 KrView *view() const 0047 { 0048 return _view; 0049 } 0050 QWidget *widget() const 0051 { 0052 return _widget; 0053 } 0054 void startDrag(); 0055 0056 void emitGotDrop(QDropEvent *e) 0057 { 0058 emit gotDrop(e); 0059 } 0060 void emitLetsDrag(QStringList items, const QPixmap &icon) 0061 { 0062 emit letsDrag(std::move(items), icon); 0063 } 0064 void emitItemDescription(const QString &desc) 0065 { 0066 emit itemDescription(desc); 0067 } 0068 void emitContextMenu(const QPoint &point) 0069 { 0070 emit contextMenu(point); 0071 } 0072 void emitEmptyContextMenu(const QPoint &point) 0073 { 0074 emit emptyContextMenu(point); 0075 } 0076 void emitRenameItem(const QString &oldName, const QString &newName) 0077 { 0078 emit renameItem(oldName, newName); 0079 } 0080 void emitExecuted(const QString &name) 0081 { 0082 emit executed(name); 0083 } 0084 void emitGoInside(const QString &name) 0085 { 0086 emit goInside(name); 0087 } 0088 void emitNeedFocus() 0089 { 0090 emit needFocus(); 0091 } 0092 void emitMiddleButtonClicked(KrViewItem *item) 0093 { 0094 emit middleButtonClicked(item); 0095 } 0096 void emitCurrentChanged(KrViewItem *item) 0097 { 0098 emit currentChanged(item); 0099 } 0100 void emitPreviewJobStarted(KJob *job) 0101 { 0102 emit previewJobStarted(job); 0103 } 0104 void emitGoHome() 0105 { 0106 emit goHome(); 0107 } 0108 void emitDirUp() 0109 { 0110 emit dirUp(); 0111 } 0112 void emitQuickCalcSpace(KrViewItem *item) 0113 { 0114 emit quickCalcSpace(item); 0115 } 0116 void emitDefaultDeleteFiles() 0117 { 0118 emit defaultDeleteFiles(); 0119 } 0120 void emitRefreshActions() 0121 { 0122 emit refreshActions(); 0123 } 0124 void emitGoBack() 0125 { 0126 emit goBack(); 0127 } 0128 void emitGoForward() 0129 { 0130 emit goForward(); 0131 } 0132 0133 /** 0134 * Search for an item by file name beginning at the current cursor position and set the 0135 * cursor to it. 0136 * 0137 * @param text file name to search for, can be regex 0138 * @param caseSensitive whether the search is case sensitive 0139 * @param direction @c 0 is for forward, @c 1 is for backward 0140 * @return true if there is a next/previous item matching the text, else false 0141 */ 0142 bool searchItem(const QString &text, bool caseSensitive, int direction = 0); 0143 /** 0144 * Filter view items. 0145 */ 0146 bool filterSearch(const QString &, bool); 0147 void setMassSelectionUpdate(bool upd); 0148 bool isMassSelectionUpdate() 0149 { 0150 return _massSelectionUpdate; 0151 } 0152 void settingsChanged(KrViewProperties::PropertyType properties); 0153 0154 public slots: 0155 void emitSelectionChanged() 0156 { 0157 if (!_massSelectionUpdate) 0158 emit selectionChanged(); 0159 } 0160 0161 void startUpdate(); 0162 void cleared(); 0163 void fileAdded(FileItem *fileitem); 0164 void fileUpdated(FileItem *newFileitem); 0165 0166 signals: 0167 void selectionChanged(); 0168 void gotDrop(QDropEvent *e); 0169 void letsDrag(QStringList items, QPixmap icon); 0170 void itemDescription(const QString &desc); 0171 void contextMenu(const QPoint &point); 0172 void emptyContextMenu(const QPoint &point); 0173 void renameItem(const QString &oldName, const QString &newName); 0174 void executed(const QString &name); 0175 void goInside(const QString &name); 0176 void needFocus(); 0177 void middleButtonClicked(KrViewItem *item); 0178 void currentChanged(KrViewItem *item); 0179 void previewJobStarted(KJob *job); 0180 void goHome(); 0181 void defaultDeleteFiles(); 0182 void dirUp(); 0183 void quickCalcSpace(KrViewItem *item); 0184 void refreshActions(); 0185 void goBack(); 0186 void goForward(); 0187 0188 protected slots: 0189 void saveDefaultSettings(); 0190 0191 protected: 0192 // never delete those 0193 KrView *_view; 0194 QWidget *_widget; 0195 0196 private: 0197 bool _massSelectionUpdate; 0198 QTimer _saveDefaultSettingsTimer; 0199 static KrViewProperties::PropertyType _changedProperties; 0200 static KrView *_changedView; 0201 }; 0202 0203 /**************************************************************************** 0204 * READ THIS FIRST: Using the view 0205 * 0206 * You always hold a pointer to KrView, thus you can only use functions declared 0207 * in this class. If you need something else, either this class is missing something 0208 * or you are ;-) 0209 * 0210 * The functions you'd usually want: 0211 * 1) getSelectedItems - returns all selected items, or (if none) the current item. 0212 * it never returns anything which includes the "..", and thus can return an empty list! 0213 * 2) getSelectedKrViewItems - the same as (1), but returns a QValueList with KrViewItems 0214 * 3) getCurrentItem, setCurrentItem - work with QString 0215 * 4) getFirst, getNext, getPrev, getCurrentKrViewItem - all work with KrViewItems, and 0216 * used to iterate through a list of items. note that getNext and getPrev accept a pointer 0217 * to the current item (used in detailedview for safe iterating), thus your loop should be: 0218 * for (KrViewItem *it = view->getFirst(); it!=0; it = view->getNext(it)) { blah; } 0219 * 5) nameToMakeCurrent(), setNameToMakeCurrent() - work with QString 0220 * 0221 * IMPORTANT NOTE: every one who subclasses this must call initProperties() in the constructor !!! 0222 */ 0223 class KrView 0224 { 0225 friend class KrViewItem; 0226 friend class KrViewOperator; 0227 0228 public: 0229 class IconSizes : public QVector<int> 0230 { 0231 public: 0232 IconSizes() 0233 { 0234 *this << 12 << 16 << 22 << 32 << 48 << 64 << 128 << 256; 0235 } 0236 }; 0237 0238 // instantiating a new view 0239 // 1. new KrView 0240 // 2. view->init() 0241 // notes: constructor does as little as possible, setup() does the rest. esp, note that 0242 // if you need something from operator or properties, move it into setup() 0243 void init(bool enableUpdateDefaultSettings = true); 0244 KrViewInstance *instance() 0245 { 0246 return &_instance; 0247 } 0248 static const IconSizes iconSizes; 0249 0250 protected: 0251 void initProperties(); 0252 KrViewOperator *createOperator() 0253 { 0254 return new KrViewOperator(this, _widget); 0255 } 0256 virtual void setup() = 0; 0257 0258 /////////////////////////////////////////////////////// 0259 // Every view must implement the following functions // 0260 /////////////////////////////////////////////////////// 0261 public: 0262 // interview related functions 0263 virtual QModelIndex getCurrentIndex() = 0; 0264 virtual bool isSelected(const QModelIndex &) = 0; 0265 virtual bool ensureVisibilityAfterSelect() = 0; 0266 virtual void selectRegion(KrViewItem *, KrViewItem *, bool) = 0; 0267 0268 virtual uint numSelected() const = 0; 0269 virtual QList<QUrl> selectedUrls() = 0; 0270 virtual void setSelectionUrls(const QList<QUrl> urls) = 0; 0271 virtual KrViewItem *getFirst() = 0; 0272 virtual KrViewItem *getLast() = 0; 0273 virtual KrViewItem *getNext(KrViewItem *current) = 0; 0274 virtual KrViewItem *getPrev(KrViewItem *current) = 0; 0275 virtual KrViewItem *getCurrentKrViewItem() = 0; 0276 virtual KrViewItem *getKrViewItemAt(const QPoint &vp) = 0; 0277 virtual KrViewItem *findItemByName(const QString &name) = 0; 0278 virtual KrViewItem *findItemByUrl(const QUrl &url) = 0; 0279 virtual QString getCurrentItem() const = 0; 0280 virtual void setCurrentItem(const QString &name, bool scrollToCurrent = true, const QModelIndex &fallbackToIndex = QModelIndex()) = 0; 0281 virtual void setCurrentKrViewItem(KrViewItem *item, bool scrollToCurrent = true) = 0; 0282 virtual void makeItemVisible(const KrViewItem *item) = 0; 0283 virtual bool isItemVisible(const KrViewItem *item) = 0; 0284 virtual void updateView() = 0; 0285 virtual void sort() = 0; 0286 virtual void refreshColors() = 0; 0287 virtual void redraw() = 0; 0288 virtual bool handleKeyEvent(QKeyEvent *e); 0289 virtual void prepareForActive() = 0; 0290 virtual void prepareForPassive() = 0; 0291 virtual void renameCurrentItem() = 0; // Rename current item. returns immediately 0292 virtual int itemsPerPage() = 0; 0293 virtual void showContextMenu(const QPoint &point = QPoint(0, 0)) = 0; 0294 0295 protected: 0296 virtual KrViewItem *preAddItem(FileItem *fileitem) = 0; 0297 virtual void preDeleteItem(KrViewItem *item) = 0; 0298 virtual void copySettingsFrom(KrView *other) = 0; 0299 virtual void populate(const QList<FileItem *> &fileItems, FileItem *dummy) = 0; 0300 virtual void intSetSelected(const FileItem *fileitem, bool select) = 0; 0301 virtual void clear(); 0302 0303 void addItem(FileItem *fileItem, bool onUpdate = false); 0304 void deleteItem(const QString &name, bool onUpdate = false); 0305 void updateItem(FileItem *newFileItem); 0306 0307 public: 0308 ////////////////////////////////////////////////////// 0309 // the following functions are already implemented, // 0310 // and normally - should NOT be re-implemented. // 0311 ////////////////////////////////////////////////////// 0312 uint numFiles() const 0313 { 0314 return _count - _numDirs; 0315 } 0316 uint numDirs() const 0317 { 0318 return _numDirs; 0319 } 0320 uint count() const 0321 { 0322 return _count; 0323 } 0324 void getSelectedItems(QStringList *names, bool fallbackToFocused = true); 0325 void getItemsByMask(const QString &mask, QStringList *names, bool dirs = true, bool files = true); 0326 KrViewItemList getSelectedKrViewItems(); 0327 void selectAllIncludingDirs() 0328 { 0329 changeSelection(KrQuery("*"), true, true); 0330 } 0331 void select(const KrQuery &filter = KrQuery("*")) 0332 { 0333 changeSelection(filter, true); 0334 } 0335 void unselect(const KrQuery &filter = KrQuery("*")) 0336 { 0337 changeSelection(filter, false); 0338 } 0339 void unselectAll() 0340 { 0341 changeSelection(KrQuery("*"), false, true); 0342 } 0343 void invertSelection(); 0344 QString nameToMakeCurrent() const 0345 { 0346 return _nameToMakeCurrent; 0347 } 0348 void setNameToMakeCurrent(const QString &name) 0349 { 0350 _nameToMakeCurrent = name; 0351 } 0352 QString firstUnmarkedBelowCurrent(const bool skipCurrent); 0353 QString statistics(); 0354 const KrViewProperties *properties() const 0355 { 0356 return _properties; 0357 } 0358 KrViewOperator *op() const 0359 { 0360 return _operator; 0361 } 0362 void showPreviews(bool show); 0363 bool previewsShown() 0364 { 0365 return _previews != nullptr; 0366 } 0367 void applySettingsToOthers(); 0368 0369 void setFiles(DirListerInterface *files); 0370 0371 /** 0372 * Refresh the file view items after the underlying file model changed. 0373 * 0374 * Tries to preserve current file and file selection if applicable. 0375 */ 0376 void refresh(); 0377 0378 bool changeSelection(const KrQuery &filter, bool select); 0379 bool changeSelection(const KrQuery &filter, bool select, bool includeDirs, bool makeVisible = false); 0380 bool isFiltered(FileItem *fileitem); 0381 void setSelected(const FileItem *fileitem, bool select); 0382 0383 ///////////////////////////////////////////////////////////// 0384 // the following functions have a default and minimalistic // 0385 // implementation, and may be re-implemented if needed // 0386 ///////////////////////////////////////////////////////////// 0387 virtual void setSortMode(KrViewProperties::ColumnType sortColumn, bool descending) 0388 { 0389 sortModeUpdated(sortColumn, descending); 0390 } 0391 const KrQuery &filterMask() const 0392 { 0393 return _properties->filterMask; 0394 } 0395 KrViewProperties::FilterSpec filter() const 0396 { 0397 return _properties->filter; 0398 } 0399 void setFilter(KrViewProperties::FilterSpec filter); 0400 void setFilter(KrViewProperties::FilterSpec filter, const FilterSettings &customFilter, bool applyToDirs); 0401 void customSelection(bool select); 0402 int defaultFileIconSize(); 0403 virtual void setFileIconSize(int size); 0404 void setDefaultFileIconSize() 0405 { 0406 setFileIconSize(defaultFileIconSize()); 0407 } 0408 void zoomIn(); 0409 void zoomOut(); 0410 0411 // save this view's settings to be restored after restart 0412 virtual void saveSettings(KConfigGroup grp, KrViewProperties::PropertyType properties = KrViewProperties::AllProperties); 0413 0414 inline QWidget *widget() 0415 { 0416 return _widget; 0417 } 0418 inline int fileIconSize() const 0419 { 0420 return _fileIconSize; 0421 } 0422 inline bool isFocused() const 0423 { 0424 return _focused; 0425 } 0426 0427 QPixmap getIcon(FileItem *fileitem); 0428 0429 void setMainWindow(QWidget *mainWindow) 0430 { 0431 _mainWindow = mainWindow; 0432 } 0433 0434 // save this view's settings as default for new views of this type 0435 void saveDefaultSettings(KrViewProperties::PropertyType properties = KrViewProperties::AllProperties); 0436 // restore the default settings for this view type 0437 void restoreDefaultSettings(); 0438 // call this to restore this view's settings after restart 0439 void restoreSettings(const KConfigGroup &grp); 0440 0441 void saveSelection(); 0442 void restoreSelection(); 0443 bool canRestoreSelection() 0444 { 0445 return !_savedSelection.isEmpty(); 0446 } 0447 void clearSavedSelection(); 0448 0449 void markSameBaseName(); 0450 void markSameExtension(); 0451 0452 // todo: what about selection modes ??? 0453 virtual ~KrView(); 0454 0455 static QPixmap getIcon(FileItem *fileitem, bool active, int size = 0); 0456 static QPixmap processIcon(const QPixmap &icon, bool dim, const QColor &dimColor, int dimFactor, bool symlink); 0457 0458 // Get GUI strings for file item properties 0459 static QString krPermissionText(const FileItem *fileitem); 0460 static QString permissionsText(const KrViewProperties *properties, const FileItem *fileItem); 0461 static QString sizeText(const KrViewProperties *properties, KIO::filesize_t size); 0462 static QString mimeTypeText(FileItem *fileItem); 0463 0464 protected: 0465 KrView(KrViewInstance &instance, KConfig *cfg); 0466 0467 virtual void doRestoreSettings(KConfigGroup grp); 0468 virtual KIO::filesize_t calcSize() = 0; 0469 virtual KIO::filesize_t calcSelectedSize() = 0; 0470 void sortModeUpdated(KrViewProperties::ColumnType sortColumn, bool descending); 0471 inline void setWidget(QWidget *w) 0472 { 0473 _widget = w; 0474 } 0475 bool drawCurrent() const; 0476 0477 KConfig *_config; 0478 KrViewProperties *_properties; 0479 KrViewOperator *_operator; 0480 bool _focused; 0481 int _fileIconSize; 0482 0483 private: 0484 void updatePreviews(); 0485 void saveSortMode(KConfigGroup &group); 0486 void restoreSortMode(KConfigGroup &group); 0487 0488 KrViewInstance &_instance; 0489 DirListerInterface *_files; 0490 QWidget *_mainWindow; 0491 QWidget *_widget; 0492 QList<QUrl> _savedSelection; 0493 QString _nameToMakeCurrent; 0494 KrPreviews *_previews; 0495 bool _updateDefaultSettings; 0496 bool _ignoreSettingsChange; 0497 QRegExp _quickFilterMask; 0498 uint _count, _numDirs; 0499 FileItem *_dummyFileItem; 0500 }; 0501 0502 #endif /* KRVIEW_H */