ciderpress/app/ContentList.h
Andy McFadden 4dd0c9339d Quick stab at Unicode for AWGS/Teach
This tweaks the output for AWGS and Teach Text to convert from Mac
OS Roman to Unicode, rather than Windows code page 1252.

It would be slightly more efficient (and possibly a bit more legible
in the RTF file) if we left the "good" conversions alone, e.g.
continue to use the CP1252 character for "E with acute", instead of
converting to U+00C9.  That might leave us at the mercy of the code
page converter in some random RTF reader, though, so it's probably
best to just use the official Unicode values.
2014-12-18 17:33:09 -08:00

284 lines
8.7 KiB
C++

/*
* 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 <afxwin.h>
#include <afxcmn.h>
/*
* 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*/