/* * CiderPress * Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved. * See the file LICENSE for distribution terms. */ /* * Declarations for a list control showing archive contents. */ #ifndef APP_CONTENTLIST_H #define APP_CONTENTLIST_H #include "GenericArchive.h" #include "Preferences.h" #include "Resource.h" #include #include /* * A ListCtrl with headers appropriate for viewing archive contents. * * NOTE: this class performs auto-cleanup, and must be allocated on the heap. * * We currently use the underlying GenericArchive as our storage for the stuff * we display. This works great until we change or delete entries from * GenericArchive. At that point we run the risk of displaying bad pointers. * * The GenericArchive has local copies of everything interesting, so the only * time things go badly for us is when somebody inside GenericArchive calls * Reload. That frees and reallocates the storage we're pointing to. So, * GenericArchive maintains a "I have reloaded" flag that we test before we * draw. */ class ContentList: public CListCtrl { public: ContentList(GenericArchive* pArchive, ColumnLayout* pLayout) { ASSERT(pArchive != NULL); ASSERT(pLayout != NULL); fpArchive = pArchive; fpLayout = pLayout; // fInvalid = false; //fRightClickItem = -1; fpArchive->ClearReloadFlag(); } /* * The archive contents have changed. Reload the list from the * GenericArchive. * * Reloading causes the current selection and view position to be lost. This * is sort of annoying if all we did is add a comment, so we try to save the * selection and reapply it. To do this correctly we need some sort of * unique identifier so we can spot the records that have come back. * * Nothing in GenericArchive should be considered valid at this point. */ void Reload(bool saveSelection = false); /* * Call this when the sort order changes. */ void NewSortOrder(void); /* * Call this when the column widths are changed programmatically (e.g. by * the preferences page enabling or disabling columns). * * We want to set any defaulted entries to actual values so that, if the * font properties change, column A doesn't resize when column B is tweaked * in the Preferences dialog. (If it's still set to "default", then when * we say "update all widths" the defaultedness will be re-evaluated.) */ void NewColumnWidths(void); /* * Copy the current column widths out to the Preferences object. */ void ExportColumnWidths(void); /* * Mark everything as selected. */ void SelectAll(void); /* * Toggle the "selected" state flag. */ void InvertSelection(void); /* * Mark all items as unselected. */ void ClearSelection(void); /* * Select the contents of any selected subdirs. */ void SelectSubdirContents(void); /* * Find the next matching entry. We start after the first selected item. * If we find a matching entry, we clear the current selection and select it. */ void FindNext(const WCHAR* str, bool down, bool matchCase, bool wholeWord); /* * Compare "str" against the contents of entry "num". */ bool CompareFindString(int num, const WCHAR* str, bool matchCase, bool wholeWord); //int GetRightClickItem(void) const { return fRightClickItem; } //void ClearRightClickItem(void) { fRightClickItem = -1; } enum { kFileTypeBufLen = 5, kAuxTypeBufLen = 6 }; /* * Get the file type display string. * * "buf" must be able to hold at least 4 characters plus the NUL (i.e. 5). * Use kFileTypeBufLen. */ static void MakeFileTypeDisplayString(const GenericEntry* pEntry, WCHAR* buf); /* * Get the aux type display string. * * "buf" must be able to hold at least 5 characters plus the NUL (i.e. 6). * Use kAuxTypeBufLen. */ static void MakeAuxTypeDisplayString(const GenericEntry* pEntry, WCHAR* buf); protected: /* * Puts the window into "report" mode, and add a client edge since we're not * using one on the frame window. */ virtual BOOL PreCreateWindow(CREATESTRUCT& cs) override; // Destroy "this". virtual void PostNcDestroy(void) override; /* * Create and populate list control. */ afx_msg int OnCreate(LPCREATESTRUCT); /* * When being shut down, save off the column width info before the window * gets destroyed. */ afx_msg void OnDestroy(void); /* * The system colors are changing; delete the image list and re-load it. */ afx_msg void OnSysColorChange(void); /* * They've clicked on a header. Figure out what kind of sort order we want * to use. */ afx_msg void OnColumnClick(NMHDR*, LRESULT*); /* * Return the value for a particular row and column. * * This gets called *a lot* while the list is being drawn, scrolled, etc. * Don't do anything too expensive. */ afx_msg void OnGetDispInfo(NMHDR* pnmh, LRESULT* pResult); private: // Load the header images. Must do this every time the syscolors change. // (Ideally this would re-map all 3dface colors. Note the current // implementation relies on the top left pixel color.) void LoadHeaderImages(void) { if (!fHdrImageList.Create(IDB_HDRBAR, 16, 1, CLR_DEFAULT)) LOGW("GLITCH: header list create failed"); fHdrImageList.SetBkColor(::GetSysColor(COLOR_BTNFACE)); } void LoadListImages(void) { if (!fListImageList.Create(IDB_LIST_PICS, 16, 1, CLR_DEFAULT)) LOGW("GLITCH: list image create failed"); fListImageList.SetBkColor(::GetSysColor(COLOR_WINDOW)); } enum { // defs for IDB_LIST_PICS kListIconNone = 0, kListIconComment = 1, kListIconNonEmptyComment = 2, kListIconDamaged = 3, kListIconSuspicious = 4, }; /* * Fill the columns with data from the archive entries. We use a "virtual" * list control to avoid storing everything multiple times. However, we * still create one item per entry so that the list control will do most * of the sorting for us (otherwise we have to do the sorting ourselves). * * Someday we should probably move to a wholly virtual list view. */ int LoadData(void); /* * Get the "selection serials" from the list of selected items. * * The caller is responsible for delete[]ing the return value. */ long* GetSelectionSerials(long* pSelCount); /* * Restore the selection from the "savedSel" list. */ void RestoreSelection(const long* savedSel, long selCount); /* * Return the default width for the specified column. */ int GetDefaultWidth(int col); /* * Convert an HFS file/creator type into a string. * * "buf" must be able to hold at least 4 characters plus the NUL. Use * kFileTypeBufLen. */ static void MakeMacTypeString(unsigned long val, WCHAR* buf); /* * Generate the funky ratio display string. While we're at it, return a * numeric value that we can sort on. * * "buf" must be able to hold at least 6 chars plus the NULL. */ static void MakeRatioDisplayString(const GenericEntry* pEntry, WCHAR* buf, int* pPerc); /* * Set the up/down sorting arrow as appropriate. */ void SetSortIcon(void); /* * Static comparison function for list sorting. */ static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); /* * Handle a double-click on an item. * * The double-click should single-select the item, so we can throw it * straight into the viewer. However, there are some uses for bulk * double-clicking. */ void OnDoubleClick(NMHDR* pnmh, LRESULT* pResult); /* * Handle a right-click on an item. */ void OnRightClick(NMHDR* pnmh, LRESULT* pResult); /* * Select every entry whose display name has "displayPrefix" as a prefix. */ void SelectSubdir(const WCHAR* displayPrefix); CImageList fHdrImageList; CImageList fListImageList; GenericArchive* fpArchive; // data we're expected to display ColumnLayout* fpLayout; // int fRightClickItem; // bool fInvalid; DECLARE_MESSAGE_MAP() }; #endif /*APP_CONTENTLIST_H*/